Spring应用(一) IOC和DI总结
2016-04-26 10:21
701 查看
一、IOC和DI的概念描述
1.1概念
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。1.2技术描述
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
1.3实现方法
实现控制反转主要有两种方式:依赖注入和依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取响应名称的对象,获得依赖对象的时间也可以在代码中自由控制。二、Spring IOC详解
Spring的控制反转:把对象的创建、初始化、销毁等工作都交给Spring容器来做。由Spring容器控制对象的声明周期。2.1步骤
A.启动spring容器
1、在类路径下寻找配置文件来实例化容器ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});可以在整个类路径中寻找xml文件 * 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下 * classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。
2、在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。
注:经常用第一种方法启动容器
B.从spring容器中提取对象
2.2 配置文件中的属性
2.2.1 别名(alias)
<beans> <bean name="person" class="cn.alias.spring.Person"/> <alias name="person" alias="p"/> </beans>
通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。
2.2.2 bean对象的scope
singleton(默认值)在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<bean id="xxx" class="cn.OrderServiceBean" lazy-init="true"/>
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“ ...>
prototype
允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的昂贵资源都是客户端的责任。
2.2.3 Lazy-init
Spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext会自动创建并配置所有的singleton bean.通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。Lazy-init=”true or false”
Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
Lazy-init 为true,spring容器将在调用该类的时候出错。
2.2.4init、destroy
Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。<bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>
当foo被载入到Spring容器中时调用init-method方法。当foo从容器中删除时调用destory-method(scope = singleton有效)
2.3 创建对象的三种方式
2.3.1 无参构造函数
<bean id=“personService" class="cn.bean.impl.PersonServiceImpl"/>
* 要求PersonServiceImpl有无参构造方法
* spring容器在默认的情况下使用默认的构造函数创建对象
2.3.2 静态工厂方法
<bean id="personService" class="com.factory.PersonServiceFactory" factory-method="createPersonService" /> public class PersonServiceFactory { public static PersonService createPersonService(){ return new PersonServiceImpl(); } }
/** * 在spring容器 内部,调用了PersonServiceFactory中的createPersonService方法 * 而该方法的内容就是创建对象的过程,是由程序员来完成 */
2.3.3 实例工厂
<bean id="helloWorldFactory" class="com.spring.ioc.createobject.method.HelloWorldFactory2"></bean> <!-- factory-bean指向了实力工厂的bean factory-method实例工厂对象的方法 --> <bean id="helloWorld" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>
/** * 实例工厂 * 1、spring容器创建一个实例工厂bean * 2、该bean调用了工厂方法getInstance产生对象 */
三、Spring DI详解
依赖注入(Dependence Injection)是把Spring创建的对象注入到Java类中有三种注入方式,分别为setter注入,构造器注入,注解注入,其中前两种方法都是在xml文件中配置
3.1 setter注入
<bean id="person" class="com.spring.di.xml.setter.Person"> <!-- property描述的就是bean中的属性 name属性就是描述属性的名称 value就是值 如果是基本属性(String),就用value赋值 ref 如果是引用类型,用ref赋值 --> <property name="pid" value="1"></property> <property name="name" value="王二麻子"></property> <property name="student" ref="student"></property> <property name="lists"> <list> <value>list1</value> <value>list2</value> <!-- list中存放一个student对象 --> <ref bean="student"/> </list> </property> <property name="objects"> <list> <value>obj1</value> <ref bean="student"/> </list> </property> <property name="sets"> <set> <value>set1</value> <ref bean="student"/> </set> </property> <property name="map"> <map> <entry key="m1"> <value>m1</value> </entry> <entry key="m2"> <ref bean="student"/> </entry> </map> </property> <property name="properties"> <props> <prop key="p1">p1</prop> <prop key="p2">p2</prop> </props> </property> </bean>
3.2 构造器注入
<bean id="person" class="com.spring.di.xml.constructor.Person"> <!-- constructor-arg 代表某一个构造器的参数 index 构造器参数的下标 value ref type 类型 --> <constructor-arg index="0" value="1" type="java.lang.String"></constructor-arg> <constructor-arg index="1" ref="student"></constructor-arg> </bean> Person类中: public Person(String name,Student student){ this.name = name; this.student = student; }
3.3 注解注入
3.3.1 步骤
步骤:A.在配置文件中,引入context命名空间
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring- beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
B.在配置文件中加入context:annotation-config标签
<context:annotation-config/>
这个配置隐式注册了多个对注释进行解析处理的处理器
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注: @Resource注解在spring安装目录的lib\j2ee\common-annotations.jar
3.3.2 @Resource
1、@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上.2、@Resource注解默认按名称装配。
名称可以通过@Resource的name属性指定,如果没有指定name属性,
•当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象
•当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
/** * 1、启动spring容器 * 2、把spring配置文件中的bean实例化(person,student) * 3、当spring容器解析配置文件 * <context:annotation-config></context:annotation-config> * spring容器会在纳入spring管理的bean的范围内查找哪些类的属性上是否加有@Resource注解 * 4、如果在属性上找到@Resource注解 * 如果@Resource的注解的name属性的值为"" * 则把@Resource所在的属性的名称和spring容器中的id作匹配 * 如果匹配成功,则赋值 * 如果匹配不成功,则会按照类型进行匹配 * 如果匹配成功,则赋值,匹配不成功,报错 * 如果@Resource的注解的name属性的值不为"" * 则解析@Resource注解name属性的值,把值和spring容器中的ID进行匹配 * 如果匹配成功,则赋值 * 如果匹配不成功,则报错 * * 说明: * 注解代码越来越简单,效率越来越低 * 注解只能应用于引用类型 */
@Autowired和@Qualifier结合起来用与@Resource效果一样
3.3.3 @Autowired
这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。3.3.4 @Qualifier
3.3.4 @PostConstruct
指定Bean的初始化方法3.3.4 @PreDestroy
指定Bean的销毁方法3.4 Spring中的继承
Spring-Context之九:在bean定义中使用继承作者:黄博文@无敌北瓜
相关文章推荐
- java单例模式生成数据库主键
- JAVA编写有图形化界面的计算器
- Java基础知识IO流(装饰设计模式)
- AutoLoadCache 与 Spring Cache 的区分
- Eclipse一直building workspace问题解决
- java 串口通信
- 元音字母的反转----java实现
- 异常处理Manual close is not allowed over a Spring managed SqlSession
- Eclipse新建Java Web项目
- myeclipse10下启动web项目报空指针的错误解决办法
- 基于springmvc mybatis junit搭建分工程,分模块的web工程框架(三)
- Spring和MyBatis实现数据的读写分离
- Eclipse 的快捷键以及文档注释、多行注释的快捷键
- Spring 定时器配置
- Java 计算年份,月份,剩余天数
- eclipse 集成svn 插件,项目无法导出的问题。
- eclipse debug 过滤一些包
- js 编码解码 与 java编码解码
- java执行script
- Java类中继承、接口实现的一些细节