Spring 注解方式实现自动检测和依赖注入

使用xml方式实现自动检测和依赖注入需要进行繁琐的xml配置,主要包括两个部分:

(1)使用<bean>...</bean>进行bean的声明;

(2)使用<property>...</property>或者<constructor-arg>...</constructor-arg>进行setter或者构造器的依赖注入

当bean数量比较少时,xml配置比较简单,但是当bean数量非常多,bean和bean之间的依赖也非常复杂,这时候再使用xml配置就会非常繁琐,维护起来也相当复杂,使用注解就相对要简单一些。

还是针对以上两个问题:

(1)Spring框架提供了bean的自动检测来解决bean的声明问题;

(2)Spring框架提供了自动装配功能来解决属性的依赖注入;

1、bean的自动检测

Spring框架提供了以下五种特殊注解来标注类。

@Component -- Spring框架通用的注解,一般用来标注不好归类的类。

@Controller -- 专用于Spring MVC的控制器注解

@Service -- 标识该类为服务

@Repository -- 标识将该类定义为数据仓库

被@Component注解标注的自定义注解

当某一个类被以上注解所标注,并且在Spring的xml文件中做一些配置(具体的配置稍后会提到),Spring框架就会自动将该类识别为一个bean并将其注册到容器中。下面这个例子就是将OracleDaoImpl用@Repository标注为数据仓库,当框架启动时,就会将该类当作一个bean注册到容器中。

package com.springframework.ioc;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

@Repository
public class OracleDaoImpl implements MyDao{
	
	private String name;
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	@Override
	public void addUser(){
		System.out.println("this is " + name + " add user...");
	}
}

 可以看到以上OracleDaoImpl类是MyDao的一个子类,MyDao类有时不止有一个实现类,除了OracleDaoImpl之外还有一个MySqlDaoImpl实现类,同样也将这个类用@Repository标注。如下:

package com.springframework.ioc;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

@Repository
public class MysqlDaoImpl implements MyDao{

	private String name;
	private int id;
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	@Override
	public void addUser(){
		System.out.println("this is " + name + " id is " + id + " add user...");
	}
}

这个时候就会有一个问题,我该如何区分这两个bean呢?在xml配置中,我们会根据bean的id来区分,同样在也可使用注解加bean id来进行区分,修改如下:

package com.springframework.ioc;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

@Repository("OracleDao")
public class OracleDaoImpl implements MyDao{
	
	private String name;
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	@Override
	public void addUser(){
		System.out.println("this is " + name + " add user...");
	}
}

 将OracleDaoImpl类声明为id为“OracleDao”的bean。

package com.springframework.ioc;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

@Repository("MysqlDao") 
public class MysqlDaoImpl implements MyDao{
	
	private String name;
	private int id;
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	public MysqlDaoImpl(){
		
	}
	public MysqlDaoImpl(String name, int id){
		this.name = name;
		this.id = id;
	}
	
	@Override
	public void addUser(){
		System.out.println("this is " + name + " id is " + id + " add user...");
	}
}

 将MysqlDaoImpl声明为id为“MysqlDao”的bean。

这个时候就可以通过bean的id来对bean进行区分,也就为后面的自动装配做好铺垫。

前面说到,要使用bean的自动检测功能,需要对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-2.5.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
			default-lazy-init="true">
			<!--对所有bean进行延迟初始化-->
			<!-- 自动扫描bean 自动装配bean -->
			<context:component-scan base-package="com.springframework.ioc"/>
			
	</beans>

使用

<context:component-scan base-package="com.springframework.ioc"/>

来指出需要自动检测的包即可。

二、自动装配

在自动检测完成bean,将bean注册到容器中后,接下来的任务就是自动装配了。

Spring框架提供了注解@Autowired标注属性、setter方法或者是构造器来解决对象的依赖问题,举例,要在service层调用dao层,则如下所示:

package com.springframework.ioc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

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

@Service("myService2")
public class MyService2{
	
	@Autowired 
        @Qualifier("OracleDao")
	private MyDao myDao;
	public MyDao getMyDao() {
		return myDao;
	}
}

 可以看到,在service层有一个myDao属性,使用@Autowired和@Qualifier来自动装配bean,其中:

使用@Autowired注解表明是自动装配,使用@Qualifier注解来指出要装配的bean的id,以便匹配。

另外需要说明的是:使用的这些注解都是Spring框架提供的,这样代码就会和Spring框架耦合比较大,可以使用基于Java的注解@Inject 和@Named()  分别对应@Autowired和@Qualified()

猜你喜欢

转载自wgfhit.iteye.com/blog/2268562