模拟实现Spring中的注解装配
作者:网络转载 发布时间:[ 2015/12/17 10:12:36 ] 推荐标签:测试开发技术 编程语言
在Spring中,XML文件中的bean配置是实现Spring IOC的核心配置文件,在早版本的Spring中,只能基于XML配置文件,配置各个对象之间的依赖关系。在Spring 2.5以后出现了注解,使用注解结合XML的方式,简化了XML配置的复杂度。
老版本中纯XML配置实现IOC
在配置文件中配置如下:
<bean id="userDao" class="com.springapp.mvc.dao.UserDao">
</bean>
<bean id="userService" class="com.springapp.mvc.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
UserServiceImpl的实现如下:
public class UserServiceImpl implements UserService {
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
private UserDao userDao;
public User getUserById(int id){
return userDao.getUserById(id);
}
public int getUserCount(){
return userDao.getUserCount();
}
}
配置的意思是:<property name="userDao" ref="userDao"></property>这行配置是为UserServiceImpl类中的userDao指定userDao这个bean,这样在UserServiceImpl类中调用userDao的方法,其实是调用com.springapp.mvc.dao.UserDao的方法。
结合注解的实现方式
配置文件简化如下:
<bean id="userDao" class="com.springapp.mvc.dao.UserDao">
</bean>
<bean id="userService" class="com.springapp.mvc.service.impl.UserServiceImpl">
</bean>
UserServiceImpl的实现如下:
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public User getUserById(int id){
return userDao.getUserById(id);
}
public int getUserCount(){
return userDao.getUserCount();
}
}
利用@Autowired注解,实现在xml中<property name="userDao" ref="userDao"></property>的配置,从而实现了自动注入。@Autowired自动注入的规则为byType,意思是按照被注解字段的类型和xml中配置的bean的类型相匹配,即在UserServiceImpl 类中的userDao为UserDao类型,匹配的时候会在所有bean中查找类型同样为UserDao的bean。
那么既然是按照类型匹配,如果存在两个相同类型的bean呢,这时候,会启用第二个匹配规则ByName,即根据字段的名字来匹配相同id的bean。如下XML配置:
<bean id="userDao1" class="com.springapp.mvc.dao.UserDao">
</bean>
<bean id="userDao2" class="com.springapp.mvc.dao.UserDao">
</bean>
<bean id="userService" class="com.springapp.mvc.service.impl.UserServiceImpl">
</bean>
那么在UserServiceImpl类中应该使用以下这种方式来自动注入:
@Autowired
private UserDao userDao1;
@Autowired
private UserDao userDao2;
这样好像不是很灵活的样子,看起来有些不爽,有没有办法可以指定要匹配的bean呢?没错,是有的。可以使用这样的方式,通过@Autowired和@Qualifier相结合的方式,@Qualifier后跟的参数是bean的名称:
@Autowired
@Qualifier("userDao1")
private UserDao userDao;
还有更常用的方式,@Resource:
@Resource(name = "userDao1")
private UserDao userDao;
关于注解IOC的内容可以参看这篇文章,写的很详细。
注解在Spring中的用法讲完了,下面来自己实习一个简单的类,来模拟Spring利用注解实现IOC的原理。
Spring IOC实现原理
1.首先Spring根据bean配置文件,收集所有bean的实例;
2.Spring根据配置文件中的context:component-scan,扫描需要被注入的包(递归包中的所有待注入类);
3.扫描待注入类时,判断是否有特定的注解(例如@Autowired、@Resource),如果有,则进行第4步,注入;
4.注入:根据注解类型或参数,利用反射,为被注解的字段或属性等设置对应的bean实例。
以上是我个人理解,可能和Spring真正的实现有些出入。
模拟利用注解实现注入
这里要定义一个类似于@Resource的注解,命名为@MyAutowired,定义如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD})
@Documented
public @interface MyAutowired {
public String name() default "";
public String value() default "";
}
定义配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:context="http://www.springframework.org/schema/context">
<context:component-scan id="test" class="fengzheng.Test"/>
<bean id="tomoto" class="fengzheng.Tomoto"></bean>
</beans>
其中bean和Spring中bean的定义是一样的,而context:component-scan在Spring是定义属性base-package,之后根据这个属性,扫描这个包下的所有类,这里为做演示,也定义为一个类,之后会根据这个class属性,对这个类进行注入。
配置文件中的tomoto bean的定义:
package fengzheng;
public class Tomoto {
public void SayHello(){
System.out.println("hello I'm tomoto");
}
}
配置文件中fengzheng.Test类定义,这个即为要被注入的类:
package fengzheng;
import fengzheng.fzAnnotation.MyAutowired;
public class Test {
@MyAutowired(name = "tomoto")
private Tomoto tomoto;
public void Say(){
tomoto.SayHello();
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11