Spring IOC详细用法

1.    简介

IOC-全称Inversion of Control,中文解释:控制反转。另外,IOC又称DI(全称)Dependency Injection,中文解释:依靠注入。

2.     注入类型

a)setter(重要)

b)构造方法(可以忘记)

c)接口注入(可以忘记)

3.     id vs. name

a)name可以用特殊字符

4.简单属性的注入

a)<property name=… value=…>

5.<bean 中的scope属性

a)singleton 单例

b)proptotype 每次创建新的对象

6.集合注入

a)很少用,不重要!参考程序

7.自动装配

a)byName

b)byType

c)如果所有的bean都用同一种,可以使用beans的属性:default-autowire

8.生命周期

a)lazy-init (不重要)

b)init-method destroy-methd 不要和prototype一起用(了解)

9.Annotation第一步:

a)修改xml文件,参考文档<context:annotation-config />

10.@Autowired

a)默认按类型by type

b)如果想用byName,使用@Qulifier

c)写在private field(第三种注入形式)(不建议,破坏封装)

d)如果写在set上,@qualifier需要写在参数上

11.@Resource(重要)

a)加入:j2ee/common-annotations.jar

b)默认按名称,名称找不到,按类型

c)可以指定特定名称

d)推荐使用

e)不足:如果没有源码,就无法运用annotation,只能使用xml

12.@Component @Service @Controller @Repository

a)初始化的名字默认为类名首字母小写

b)可以指定初始化bean的名字

以下是详细测试代码,部分代码已经被注释,方便测试

xml测试:

1、model

package dhp.model;

public class User {
	private String username;
	private String password;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

2、dao

package dhp.dao;

import dhp.model.User;

public interface UserDao {
	public void save(User user);
}

3、daoimpl

package dhp.dao.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import dhp.dao.UserDao;
import dhp.model.User;

public class UserDaoImpl implements UserDao {
	private int daoId;
	//private String daoStatus;
	
	public int getDaoId() {
		return daoId;
	}

	public void setDaoId(int daoId) {
		this.daoId = daoId;
	}

	/*public String getDaoStatus() {
		return daoStatus;
	}

	public void setDaoStatus(String daoStatus) {
		this.daoStatus = daoStatus;
	}
  */
	private Set<String> sets;
	private List<String> lists;
	private Map<String, String> maps;
	
	public Set<String> getSets() {
		return sets;
	}
	public void setSets(Set<String> sets) {
		this.sets = sets;
	}
	public List<String> getLists() {
		return lists;
	}
	public void setLists(List<String> lists) {
		this.lists = lists;
	}
	public Map<String, String> getMaps() {
		return maps;
	}
	public void setMaps(Map<String, String> maps) {
		this.maps = maps;
	}
	@Override
	public void save(User user) {
		System.out.println("user saved!");
		//System.out.println("daoId:==="+daoId+"daoStatus:==="+daoStatus);
	}
	@Override
	public String toString() {
		
		/*return "sets size:" + sets.size() + "| lists size:" + lists.size() + 
				"| maps size:" + maps.size();*/
		return "daoId:"+daoId;
	}

}

4、service

package dhp.service;

import dhp.dao.UserDao;
import dhp.model.User;

public class UserService {
	private UserDao userDao;
	//构造方法注入
	/*public UserService(UserDao userDao) {
		super();
		this.userDao = userDao;
	}*/
	
	public void init(){
		System.out.println("=========init");
	}
	
	public void add(User user){
		userDao.save(user);
	}
	public UserDao getUserDao() {
		return userDao;
	}
	//set方式注入
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public void destroy(){
		System.out.println("==========destroy");
	}
}

5、test

package dhp.service;

import static org.junit.Assert.*;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dhp.dao.UserDao;
import dhp.model.User;

public class UserServiceTest {

	@Test
	public void testAdd() {
		
	   //ClassPathXmlApplicationContext继承自ApplicationContext,而ApplicationContext继承自BeanFactory
		//推荐使用
		//创建IOC容器
		ClassPathXmlApplicationContext ctx =new ClassPathXmlApplicationContext("beans.xml");
		//从IOC容器中得到bean的对象实例
		UserService userService = (UserService) ctx.getBean("userService");
	
		//UserService userService2 = (UserService) ctx.getBean("userService");
		//System.out.print("验证singleton和prototype:");
		//System.out.println(userService==userService2);//为 true,说明我们取出的是同一个对象
		
		ctx.destroy();   //destroy必须手动指定,因为web环境下会自动destroy,必须是ClassPathXmlApplicationContext,不会监控prototype,只会监控singleton
		
		
		/*BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");
		UserService userService = (UserService) applicationContext.getBean("userService");*/
		
		User user = new User();
		user.setUsername("dhp");
		user.setPassword("123456");
		
		userService.add(user);
		
		
		//测试collection
		/*UserDao userDao = (UserDao) ctx.getBean("userDao");
		System.out.println(userDao);*/
		
		//测试byName和byType
		System.out.println("=========="+userService.getUserDao());
		
	}

}

6、beans.xml

<?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.xsd"
            >
            <!-- 放在beans里面 -->
<!-- default-lazy-init="default"全局不启动 --> 
<!-- default-autowire="default" 全局的自动注入-->

  <bean id="userDao" class="dhp.dao.impl.UserDaoImpl"><!-- id也可以写出name, 只不过name是可以支持特殊字符的 -->
  <!-- 简单属性注入,很少使用 -->
      <!-- <property name="daoId" value="10"></property>
      <property name="daoStatus" value="working"></property> -->
      
      <!-- 集合 -->
 <!--<property name="sets"> 相当于调用了setSets(Set<String> sets)
          <set>
             <value>1</value>
             <value>2</value>
          </set>
      </property>
      
      <property name="lists">相当于调用了setLists(List<String> lists)
          <list>
             <value>A</value>
             <value>B</value>
             <value>C</value>
          </list>
      </property>
      
      <property name="maps"> 相当于调用了setMaps(Map<String, String> maps)
          <map>
             <entry key="1" value="map1"></entry>
             <entry key="2" value="map2"></entry>
             <entry key="3" value="map3"></entry>
             <entry key="4" value="map4"></entry>
          </map>
      </property> -->
      
      <!-- <property name="">
           <props>
              <prop key="">...</prop>
              <prop key="">...</prop>
              <prop key="">...</prop>
           </props>
      </property> -->
      <property name="daoId" value="100"></property>
      
  </bean>

  <bean id="userDao2" class="dhp.dao.impl.UserDaoImpl" lazy-init="true"><!--设为true, new 的时候不启动 -->
      <property name="daoId" value="200"></property>
  </bean>
<!-- 自动注入时,不能有构造方法 -->
<!-- byName要求必须id和service里的属性一致 -->

<!-- byName:在容器中寻找和需要自动装配的属性名相同的Bean(或ID),如果没有找到相符的Bean,该属性就没有被装配上。 -->
<!-- byType:在容器中寻找一个与需要自动装配的属性类型相同的Bean;
         如果没有找到相符的Bean,该属性就没有被装配上,如果找到超过一个相符的Bean抛出异常 -->
<!-- constructor 与byType方式类似,不同之处在于它应用于构造器参数。
                                        如果容器中没有找到与构造器参数类型一致的bean,
                                        那么抛出异常。 -->
<!-- default: <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.xsd"
            default-autowire="default">
            -->                
   <!-- scope默认是 singleton -->
  <bean id="userService" class="dhp.service.UserService" scope="singleton" autowire="byName" init-method="init" destroy-method="destroy">
     <!-- 方式1.1 -->
     <!-- <property name="userDao" ref="userDao"></property> -->
     
     <!-- 方式1.2 -->
     <!-- <property name="userDao">
        <ref bean="userDao"/>
     </property> -->
     
     <!-- 方式2 -->
     <!-- <constructor-arg>
        <ref bean="userDao"/>
     </constructor-arg> -->
  </bean>

</beans>




       注解测试:

1、daoimpl

package dhp.dao.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Component;

import dhp.dao.UserDao;
import dhp.model.User;
@Component("userDaoImpl")
public class UserDaoImpl implements UserDao {
	private int daoId;
	//private String daoStatus;
	
	public int getDaoId() {
		return daoId;
	}

	public void setDaoId(int daoId) {
		this.daoId = daoId;
	}

	/*public String getDaoStatus() {
		return daoStatus;
	}

	public void setDaoStatus(String daoStatus) {
		this.daoStatus = daoStatus;
	}
  */
	private Set<String> sets;
	private List<String> lists;
	private Map<String, String> maps;
	
	public Set<String> getSets() {
		return sets;
	}
	public void setSets(Set<String> sets) {
		this.sets = sets;
	}
	public List<String> getLists() {
		return lists;
	}
	public void setLists(List<String> lists) {
		this.lists = lists;
	}
	public Map<String, String> getMaps() {
		return maps;
	}
	public void setMaps(Map<String, String> maps) {
		this.maps = maps;
	}
	@Override
	public void save(User user) {
		System.out.println("user saved!");
		//System.out.println("daoId:==="+daoId+"daoStatus:==="+daoStatus);
	}
	@Override
	public String toString() {
		
		/*return "sets size:" + sets.size() + "| lists size:" + lists.size() + 
				"| maps size:" + maps.size();*/
		return "daoId:"+daoId;
	}

}

2、service

package dhp.service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import dhp.dao.UserDao;
import dhp.model.User;

@Component("userService")
public class UserService {
	private UserDao userDao;
	//构造方法注入
	/*public UserService(UserDao userDao) {
		super();
		this.userDao = userDao;
	}*/
	@PostConstruct
	public void init(){
		System.out.println("=========init");
	}
	
	public void add(User user){
		userDao.save(user);
	}
	public UserDao getUserDao() {
		return userDao;
	}
	//set方式注入
	/*@Autowired//默认通过byType
	public void setUserDao(@Qualifier("userDao2") UserDao userDao) {
		this.userDao = userDao;
	}*/
	//@Resource(name="userDao2")//默认按名称,名称找不到时,通过byType
	@Resource(name="userDaoImpl") //name的指定配合@Component("userDaoImpl")的使用
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	@PreDestroy
	public void destroy(){
		System.out.println("==========destroy");
	}
}

3、test

package dhp.service;

import static org.junit.Assert.*;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dhp.dao.UserDao;
import dhp.model.User;

public class UserServiceTest {

	@Test
	public void testAdd() {
	   //ClassPathXmlApplicationContext继承自ApplicationContext,而ApplicationContext继承自BeanFactory
		//推荐使用
		ClassPathXmlApplicationContext ctx =new ClassPathXmlApplicationContext("beans.xml");
		UserService userService = (UserService) ctx.getBean("userService");
		
		userService.add(new User());
		System.out.println(userService.getUserDao());
		
		ctx.destroy();
	}

}

4、beans.xml

<?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.xsd
            http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">
         
  <!--  初始化了AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor,
     PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor -->
     
<context:annotation-config/> <!-- 初始化4个 -->       <!-- @autowired, @resource -->
<context:component-scan base-package="dhp"/>     <!-- 扫描@Component @Service @Controller @Repository 减少bean配置  -->

  <!-- <bean id="userDao" class="dhp.dao.impl.UserDaoImpl">
     <property name="daoId" value="100"></property>
  </bean>
  
   <bean id="userDao2" class="dhp.dao.impl.UserDaoImpl">
      <property name="daoId" value="200"></property>
   </bean> -->

 <!--  <bean id="userService" class="dhp.service.UserService">

  </bean>
 -->
</beans>


附:

1.bean的自动装配和自动检测的区别

启用注解装配,在xml配置文件里添加:<context:annotation-config/>

启用自动扫描注解,在xml配置文件里添加:<context:component-scan base-package="dhp"/>

二者的区别: 自动装配表示通过@Autowired, @Inject, @Resource等实现对属性或构造函数的自动注入;仍然需要在配置文件里定义bean,只是通过

自动装配省去了property和constructor-arg的配置。 自动检测是扫描特定的注解(包括:@Component, @Controller, @Service, @Repository),将注

解过的类自动定义为bean,自动检测是自动装配的超集,通过自动检测,可以省去在xml配置文件里定义bean了。


2. 通过自动装配和注解实现注入

在xml配置文件里启动注解装配:<context:annotation-config/>

定义bean:

<bean id="userDao" class="dhp.dao.impl.UserDaoImpl">
     <property name="daoId" value="100"></property>
  </bean>

然后在需要注入的属性上或者其setter方法上,或者构造函数上,添加@Autowired, @Inject, @Resource等注解实现自动注入:

//set方式注入
//@Autowired
       //@Inject
       @Resource
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

@Autowired, @Inject, @Resource的区别:@Autowired是Spring 3.0的注解,是通过byType形式实现注解,可以通过@Qualifier根据bean的id进行限定;使用@Autowired注解即引入了对Spring的依赖。@Inject是JSR 330的注解,使用该注解需要导入包javax.inject,@Named(value=”“)可以根据bean的id进行限定;@Resource是JSR 250的注解,可以通过value限定bean的id,如@Resource(value=””);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值