标签:
个人感觉依赖注入比控制反转更好理解,所以下面就只说依赖注入:
spring的整体结构示意图:
1、容器是spring框架的核心,容器使用ioc依赖注入来管理所有组成应用系统的组件。
2、spring中的两种容器: beanFactory 这个容器提供了基础的依赖注入支持,而且是延迟加载的,而 applicationcontext是对beanFactory 这个容器的扩展,
3、beanFactory :beanFactory就是一个Bean工厂,使用了工厂模式,但bean工厂不像一般的工厂,只提供特定类的bean而是一个通用的工厂,可以创建和分发各种类型的bean,beanFactory不仅仅只是创建和分发bean因为我们知道,这个bean工厂知道应用中的很多对象,在创建这些对象的时候,创建出了这些对象之间的关联关系,bean工厂还管理这些对象的生命周期。
4、beanFactory 接口的实现类有很多,我们这里就举一个常用的类: XMLBeanFactory, XMLBeanFactory构造方法的参数是一个inputStream对象,而传递进来的就是我们定义bean的xml文件
5、实例:BeanFactory beanfactory = new XMLBeanFactory(newFileInputStream(bean.xml)); 这样beanFactory就获取了配置文件中bean的信息,但是bean是延迟实例化的所以现在只是加载进来了,但还是没有创建实例,只有在使用的时候尽心创建
6、 User user=(User)beanfactory.getBean("user");
当我们调用getBean()时工厂会实例化并且会依赖注入设置相关属性值。
1、applicationcontext和beanFactory看来都是一样的,都是加载bean的信息,配置bean和分发bean,但是application
context作为beanFactory的扩展有一些额外的功能:(1)文本信息解析工具,包括对国际化的支持(2)应用上下文提供了载入文件资源的通用方法(3)应用上下文可以向注册为监听器的bean发送事件,因为application
context的额外功能所以在应用中大都使用application context而beanFactory在资源较少的移动设备上使用
2、ApplicationContext的实现:ClassPathXmlApplicationContext()类路劲中的xml文件中载入上下文信息,FileSystemXmlApplicationContext()文件系统xml获取上下文信息
XmlWebApplicationContext()从网络获取上下文信息。
3、我们知道 ApplicationContext是对beanFactory的扩展所以我们同样可以使用 .getBean("User")来获取对象,但是这里有点不同,那就是在beanFactory中使用的就是懒加载,在调用getBean()的时候才会创建实例而ApplicationContext () 在上下文预加载的时候就创建了实例,在使用的时候不用等待创建而是直接使用。
1、容器寻找bean的定义信息,并且实例化bean
2、使用依赖注入,spring按照bean定义信息配置bean的所有属性
3、如果bean实现了BeanNameAware接口则工厂调用bean的setBeanName() 方法传递bean的Id
4、如果bean实现了beanFacgtoryAware 接口则工厂调用 setBeanFactory()方法传入工厂本身。
5、如果有BeanPostProcess和bean关联那么他们的PostProcessBeforeInitialzation()方法将被调用
6、如果bean指定了init-method 方法则将被调用
7、如果有BeanPostProcess和bean关联那么他们的PostProcessAfterInitialzation()方法将被调用
到这里bean就可以在系统中被使用了,并将一直保存在BeanFactory 中直到他不在使用。
8、删除: spring 中有两种方式:(1)、如果bean实现了Disposable接口则destory方法将会被调用(2)、自己定义定义了销毁方法则执行他 destroy-method
1、所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。
在spring容器内拼凑bean叫做装配,装配bean的时候你是在告诉容器需要哪些bean,以及容器如何使用依赖注入将他们配合在一起。
1、在使用spring容器进行bean类的管理的时候,我们获取bean类有两种类型,一种就是在spring中使用了单例模式,获取的都是第一次加载的时候创建的那个bean实例,第二种就是在spring中没有定义单例模式,每获取一次就会产生一个新的bean实例。
区别这两种的配置:
<beanid="user" class="com.inspur.User" singleton=off>
</bean>
// singleton(单一的 唯一的) 这里关闭了单例模式,所以每次获取的bean对象都是新的,而在spring中singleton默认是开着的,因为像数据库连接池,网络资源等创建新对象很浪费资源,所以还是使用单例模式比较好,如果没有特别需求还是使用单例模式比较好!
<beanid="user" class="com.inspur.User">
<propertyname="name">
<value>"Name"</value>
</property>
<propertyname="age">
<value>12</value>
</property>
</bean>
或
<beanid="user" class="com.inspur.User">
<property name="name" value="name"/>
<property name="age" value=12 />
</bean>
//这种方式就是set注入,所谓的注入也就是给spring中的bean的属性赋值
<beanid="user" class="com.inspur.User">
<propertyname="name">
<value>"Name"</value>
</property>
<propertyname="address">
<ref bean="otherBeanId"/> // 属性的值为某一实例,所以进行了引用
</property>
</bean>
或
如果某个属性的值为其他的类,则可以按如下操作完成
<beanid="user" class="com.inspur.User">
<propertyname="name" value="name">
<propertyname="address" ref="otherBeanId">// 属性的值为某一实例,所以进行了引用
</bean>
<property name="list">
<list>
<value>1</value> // 这里的value可以是任何类型
<value>2</value>
</list>
</property>
这个没见过但是他的使用方式和map一样,但是他的值只是 string类型所以就不用value了:
特殊的值:将某个属性的值设置为null:
<beanid="user" class="com.inspur.User">
<constructor-arg>
<value>Name</value>
</constructor-arg>
</bean>
<beanid="user" class="com.inspur.User">
<constructor-arg type="java.lang.String"> // 标明参数的类型
<value>"6"</value>
<constructor-arg>
<constructor-arg type="int"> // 标明参数的类型
<value>8</value>
<constructor-arg>
</bean>
<beanid="user" class="com.inspur.User">
<constructor-arg index=0> // 是从0开始的
<value>6</value>
</constructor-arg>
<constructor-arg index=1>
<value>8</value>
</constructor-arg>
</bean>
使用构造函数进行依赖注入,有个问题那就是不确定性,那个值赋给那个变量:解决方式有两种,即 index和type这两个属性index=“0”index=“1”这个就是来确定构造函数中第一个第二个参数的。
而type=“int”或type="java.lang.String"这个就是一个构造函数中有不同类型的参数的时候我们使用type来确定。
总的来说构造函数注入的方式还是有不确定性,因为有的时候如果有过个构造函数等情况就没办法处理了。
上面的那种注入方式都是手动注入,下面我们看看spring中的自动注入:
例:
springtest中有个属性就是Student student;
<bean id="springtest" class="com.inspur.imp.SpringTest" autowire="byName"/>
// 这里是按照名称来自动注入的 也就是SpringTest 这个类中有个Student student 属性 而使用byName方式来注入的时候就会将id=student 的这个bean注入到 SpringTest的Student student这个属性上。
<bean id="student" class="com.inspur.imp.Student">
<propertyname="age">
<value>12</value>
</property>
<propertyname="name">
<value>"stuname"</value>
</property>
</bean>
<bean id="springtest" class="com.inspur.imp.SpringTest" autowire="byType"/>
自动注入--constructor(按照构造函数来注入):
<bean id="springtest" class="com.inspur.imp.SpringTest" autowire="constructor"/>
自动注入---使用何种注入方式,可以让容器自己选择:
<bean id="springtest" class="com.inspur.imp.SpringTest" autowire="autodetect"/>
自动注入减少了配置,但是这样会带来很多麻烦因为有可能找不到,就会报异常,而且平时使用最多的也就是比较方便的set注入
标签:
原文地址:http://blog.csdn.net/qh_java/article/details/43636757