`

Spring IOC笔记

阅读更多

1、概念:

      Ioc:控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。

  DI:依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。依赖注入是时下最流行的Io实现方式,注入方式分这三种:

  a).接口注入(Interface Injection),

  b).设值注入(Setter Injection),

  c).构造器注入(Constructor Injection)。

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl">
		<!-- 构造器注入 -->
		<!-- ①index索引指定对应传参 -->
		<constructor-arg index="0" value="jdbc:oracle:thin:@hostip:1521:dbname" />
		<constructor-arg index="1" value="true" />
		<!-- ②name参数名称指定对应传参 -->
<!--		<constructor-arg name="url" value="jdbc:oracle:thin:@hostip:1521:dbname" />-->
<!--		<constructor-arg name="show_Log" value="true" />-->
		<!-- ③type类型名称指定对应传参 -->
<!--		<constructor-arg type="0" value="jdbc:oracle:thin:@hostip:1521:dbname" />-->
<!--		<constructor-arg type="1" value="true" />-->
	</bean>
	<bean id="userService" class="com.bjsxt.service.UserService">
		<!-- setter注入 -->
		<property name="userDao" ref="u" />
	</bean>
</beans>

 

 

 2、id和name的区别:定义一个bean的时候,可以用id也可以用name,比如:

<bean id="userService" class="com.bjsxt.service.UserService">
		<property name="userDao" ref="u" />
	</bean>
<bean name="userService" class="com.bjsxt.service.UserService">
		<property name="userDao" ref="u" />
	</bean>

 

 两者是等效的,区别在于name里面可以含特殊字符而id不行。

 

3、简单属性的注入:很少用,一般在定义数据库驱动、url、用户名、密码的时候可以用简单属性注入的方式注入这些常量。

 

4、bean的作用域(生存范围):

      a).singleton : 默认值,单例,表示容器初始化完了之后,每次getbean()拿到的都是同一个对象。

      b).prototype : 原型,每次拿到的都是按照原型重行构造出来的新对象。

      c).其它:request/session/global/application

 

5、集合注入

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- results in a setAdminEmails(java.util.Properties) call -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- results in a setSomeList(java.util.List) call -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- results in a setSomeMap(java.util.Map) call -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- results in a setSomeSet(java.util.Set) call -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
</bean>

 

6、自动装配:在<bean>中配置autowire属性,通常属性值会用到"byName"和"byType",配置之后,spring容器会根据类中属性名称或者类型自动将指定的bean注入到类中。

<bean name="userDao" class="com.bjsxt.dao.impl.UserDAOImpl">
		<property name="daoId" value="1"></property>
	</bean>
	<bean id="userService" class="com.bjsxt.service.UserService" scope="prototype" autowire="byName">
	</bean>

 如上例,UserService类中如果有名称为userDao的属性,那么UserDAOImpl类将被自动注入到UserService类中。

也可以在<beans>标签中配置default-autowire属性,统一为所有的bean指定自动装配的方式。

 

7、懒加载(lazy-init):在<bean>中添加lazy-init="true",那么在容器启动的时候,不会初始化这个类,直到在程序中getBean()获取这个类的时候才初始化;同样也可以在<beans>中添加default-lazy-init="true",这样所有的bean统一被设置成了懒加载。这个功能大多数情况都用不到,但是在系统启动非常慢的情况下可以考虑加此功能。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
	default-lazy-init="true">

	<bean name="userDao" class="com.bjsxt.dao.impl.UserDAOImpl">
		<property name="daoId" value="1"></property>
	</bean>
	<bean id="userService" class="com.bjsxt.service.UserService"
		lazy-init="true"  autowire="byType">
	</bean>
</beans>

 

 8、bean的生命周期(lifecycle):

      在<bean>中配置init-method属性指定bean初始化之后调用的方法,如:init-method="init";也可以实现InitializingBean接口,重写其afterPropertiesSet()方法。同样的,

      在<bean>中配置destroy-method属性指定bean销毁之前调用的方法,如:destroy-method="destroy";也可以实现DisposableBean接口,重写其destroy()方法,需要注意的是不要和scope="prototype"一起使用,否则容器不负责各个bean的销毁,即调用容器(AbstractApplicationContext)的close()方法无效。

可以在<beans>中配置default-init-method和default-destroy-method属性为所有bean统一指定初始化之后及销毁之前调用的方法。

初始化及销毁方法的重写可用于日志功能,指定销毁的方法,可在其中关闭数据库连接等等。

	<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl">
		<constructor-arg index="0" value="jdbc:oracle:thin:@hostip:1521:dbname" />
		<constructor-arg index="1" value="true" />
	</bean>
	<bean id="userService" class="com.bjsxt.service.UserService" init-method="initMethod" destroy-method="destroyMethod">
		<property name="userDao" ref="u" />
	</bean>

 

package com.panda.service;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import com.panda.dao.UserDAO;
import com.panda.model.User;
public class UserService implements InitializingBean,DisposableBean{
	
	private UserDAO userDao;
	
	public void initMethod() {
		System.out.println("属性destroy-init的方式init");
	}
	
	public void add(User u){
		this.userDao.save(u);
	}

	public UserDAO getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDAO userDao) {
		this.userDao = userDao;
	}
	
	public UserService(){}

	public UserService(UserDAO userDao) {
		super();
		this.userDao = userDao;
	}
	
	public void destroyMethod(){
		System.out.println("属性destroy-method的方式destroy");
	}

	//实现InitializingBean接口方法
	public void afterPropertiesSet() throws Exception {
		System.out.println("实现InitializingBean接口的方式init");
		
	}

	//实现DisposableBean接口方法
	public void destroy() throws Exception {
		System.out.println("实现DisposableBean接口的方式destory");
		
	}
}

 

9、注解(Annotation)

      在配置文件中添加<context:annotation-config/>,容器初始化之后,检查有此配置的话,会去实例化注解相关的 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor,

PersistenceAnnotationBeanPostProcessor和 RequiredAnnotationBeanPostProcessor四个类,

为类里面的注解提供支持、处理。

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
	<context:annotation-config></context:annotation-config>
	<bean id="u1" class="com.bjsxt.dao.impl.UserDAOImpl">
		<property name="id" value="1"></property>
	</bean>
	<bean id="u2" class="com.bjsxt.dao.impl.UserDAOImpl">
		<property name="id" value="2"></property>
	</bean>
	<bean id="userService" class="com.bjsxt.service.UserService">
	</bean>
</beans>

 

     a).@Autowired:自动装配注解。默认是byType注入,当有多个同类型的bean时,使用@Qualifier("")进行区分(也可以在<bean>中配置<qualifier value="first"></qualifier>来区分同类型的不同bean,然后注解则可以写成@Qualifier("first"))。注解可以加在setter上(用@Autowired注解时方法名不一定是setter形式),也可以加在成员变量上。

 

package com.panda.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.panda.dao.UserDAO;
import com.panda.model.User;

public class UserService{
	
	private UserDAO userDao;
	
	public void add(User u){
		this.userDao.save(u);
	}

	public UserDAO getUserDao() {
		return userDao;
	}

	@Autowired
	public void setUserDao(@Qualifier("u1")UserDAO userDao) {
		this.userDao = userDao;
	}
}

   b).@Resource,作用与@Autowired一样。默认按name查找,找不到按type查找。

   c).@Component,需要在配置文件中加入<context:component-scan base-package="com.panda"/>,将此注解加在类头部,即将类初始化为组件放在容器中作为一个bean存在,然后在代码中方法上面使用@Resource即可注入。

    @Repository@Service@Controller注解也都有此功能。

    d).@Scope,与bean中配置scope属性的作用一直。如scope="prototype"与@Scope("prototype").

  e).@PostConstrut和@PreDestroy,作用等同于在bena中配置的init-method和init-destroy,配置在方法上,指定bean初始化之后和销毁之前的方法。

  

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics