欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring IOC笔记

程序员文章站 2022-05-02 23:26:29
...

1、概念:

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

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

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

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

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

Spring IOC笔记
            
    
    博客分类: Spring springIOC控制反转依赖注入Annotation 

 

<?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初始化之后和销毁之前的方法。