学框架不学spring都很差意思跟别人说本身懂框架,并且如今好多java方面的工做要求熟练spring/myBaits等主流框架,本身学 spring也有一段时间了,作一篇博客整理下本身的思路,技术吗,不沉淀下来终究没法转化成本身的东西,之因此写的通俗一点,权且是对本身渣比的调侃吧。java
从spring的两大思想开始:1.IOC; 2.AOPspring
IOC(inversion of control),控制反转,这里的控制是指控制对象的建立,众所周知,java中是经过new关键字来建立对象的,有些仅仅使用一次的对象反复建立,造 成了资源的浪费,若是将对象的建立交付给容器,不只能省去大量资源使对象复用,更能省去某些麻烦(反复new对象形成的麻烦应该不仅资源浪费,猜想)。个 人感受,设计模式的重要想法就是专门弄一项技术来处理某些专门的需求,正是对象资源的管理催生了ioc,将对象管理交给容器来管理,须要对象时候从容器里 面拿一个就好,是否是很方便,哈哈。所谓容器,实现起来就是由jvm建立和管理一块专门放对象的内存,容器的启动,初始化,销毁特性归纳起来就是生命周 期,spring正是在容器的生命周期内完成对象的管理的。下面是new对象方式和ioc方式处理对象的对照:编程
public class Car{ public car(){ //汽车初始化时候也要初始化发动机 Egnine eg=new Egnine(); } } //使用时候 Car car=new Car();
使用ioc方式,把对象的关系写在xml文件中,这样汽车一初始化的时候,引擎也随之初始化,就是把它们的建立关系写在另一个擅长逻辑关系管理的文件中,这种文件名字叫xml.
这样作的另一个好处就是,若是一个car须要两个引擎,把xml改掉以后原来代码照样跑,有个高大上的名字叫-解耦,须要什么在bean的配置文件里面嵌套一些bean做为参数,这种
方式称之为注入.
Step 1
<bean id="Car" class="cn.usct.Car">
<constructor-arg ref="eg"></constructor-arg>
</bean>
<bean id="eg" class="cn.usct.Egnine"></bean>
Car和Egnine的代码照常(ioc只提供对象管理,但对象是什么样子仍是靠.java文件里的类)
Step 2
Car c=ApplicationContext.get("Car");
spring3和spring2.5的一大区别就是经过id的getBean()方法还须要用a.class做为第二个参数设计模式
第一个spring使用:数组
1.建立项目,导入jar包,项目结构:“src”用于存放java文件;“lib”用于存放jar文件;“resources”用于存放配置文件框架
2.写接口和实现类dom
3.jvm
- ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
-
- HelloApi helloApi = context.getBean("hello", HelloApi.class);
-
- helloApi.sayHello();
最经常使用API:Object getBean(String name) 根据名称返回一个Bean,客户端须要本身进行类型转换;ide
二,获取bean的方式(四种)测试
id,类(car.class),名字+类
三,实例化
1.<constructor-args index="0" value="hello!"/> 为一个参数的构造方法提供了字符串类型参数
2.普通工厂实例化
- package cn.javass.spring.chapter2;
- public class HelloApiInstanceFactory {
- public HelloApi newInstance(String message) {
- return new HelloImpl2(message);
- }
- }
xml
- <!—1、定义实例工厂Bean -->
- <bean id="beanInstanceFactory"
- class="cn.javass.spring.chapter2.HelloApiInstanceFactory"/>
- <!—2、使用实例工厂Bean建立Bean -->
- <bean id="bean4"
- factory-bean="beanInstanceFactory"
- factory-method="newInstance">
- <constructor-arg index="0" value="Hello Spring!"></constructor-arg>
- </bean>
测试代码
- BeanFactory beanFactory =
- new ClassPathXmlApplicationContext("chapter2/instantiatingBean.xml");
- HelloApi bean4 = beanFactory.getBean("bean4", HelloApi.class);
- bean4.sayHello();
四,注入
1.
构造方法注入:index,name,type
- <!-- 经过构造器参数索引方式依赖注入 -->
- <bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg index="0" value="Hello World!"/>
- <constructor-arg index="1" value="1"/>
- </bean>
- <!-- 经过构造器参数类型方式依赖注入 -->
- <bean id="byType" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg type="java.lang.String" value="Hello World!"/>
- <constructor-arg type="int" value="2"/>
- </bean>
- <!-- 经过构造器参数名称方式依赖注入 -->
- <bean id="byName" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg name="message" value="Hello World!"/>
- <constructor-arg name="index" value="3"/>
- </bean>
不建议使用name注入
2.
2.1注入普通属性
setter方法注入
1.类文件
- package cn.javass.spring.chapter3;
- import cn.javass.spring.chapter2.helloworld.HelloApi;
- public class HelloImpl4 implements HelloApi {
- private String message;
- private int index;
- public void setMessage(String message) {
- this.message = message;
- }
- public void setIndex(int index) {
- this.index = index;
- }
- @Override
- public void sayHello() {
- System.out.println(index + ":" + message);
- }
- }
2.配置bean,主要是property
- <!-- 经过setter方式进行依赖注入 -->
- <bean id="bean" class="cn.javass.spring.chapter3.HelloImpl4">
- <property name="message" value="Hello World!"/>
- <property name="index">
- <value>1</value>
- </property>
- </bean>
2.2注入集合
1类
- package cn.javass.spring.chapter3.bean;
- import java.util.List;
- public class ListTestBean {
- private List<String> values;
- public List<String> getValues() {
- return values;
- }
- public void setValues(List<String> values) {
- this.values = values;
- }
- }
2注入
- <bean id="listBean" class="cn.javass.spring.chapter3.bean.ListTestBean">
- <property name="values">
- <list>
- <value>1</value>
- <value>2</value>
- <value>3</value>
- </list>
- </property>
- </bean>
3测试
- @Test
- public void testListInject() {
- BeanFactory beanFactory =
- new ClassPathXmlApplicationContext("chapter3/listInject.xml");
- ListTestBean listBean = beanFactory.getBean("listBean", ListTestBean.class);
- System.out.println(listBean.getValues().size());
- Assert.assertEquals(3, listBean.getValues().size());
- }
Assert.assertEquals();方法判断先后两个值是否相等
set集合类型与之相同
3
注入其余bean
- <bean id="bean2" class="cn.javass.spring.chapter3.bean.HelloApiDecorator">
- <property name="helloApi"><ref bean=" helloApi"/></property>
- </bean>
注入总结
1、构造器注入:
1)常量值
简写:<constructor-arg index="0" value="常量"/>
全写:<constructor-arg index="0"><value>常量</value></constructor-arg>
2)引用
简写:<constructor-arg index="0" ref="引用"/>
全写:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>
2、setter注入:
1)常量值
简写:<property name="message" value="常量"/>
全写:<property name="message"><value>常量</value></ property>
2)引用
简写:<property name="message" ref="引用"/>
全写:<property name="message"><ref bean="引用"/></ property>
3)数组:<array>没有简写形式
4)列表:<list>没有简写形式
5)集合:<set>没有简写形式
6)字典
简写:<map>
<entry key="键常量" value="值常量"/>
<entry key-ref="键引用" value-ref="值引用"/>
</map>
全写:<map>
<entry><key><value>键常量</value></key><value>值常量</value></entry>
<entry><key><ref bean="键引用"/></key><ref bean="值引用"/></entry>
</map>
7)Properties:没有简写形式
ps:null值注入
<property name="name"></null></>
(原理篇)
还有一个问题,ioc是如何实现的?
个人理解是依靠反射,基于dom解析器的解析原理,当读到一个id时候,按照符合ioc的dtd,class里面理应是这个bean的实现类,本质上仍是经过new来建立而且返回,只是spring默认的是单例模式,那么建立以前先加判断 if(instance==null){建立}