模拟实现Spring中的注解装配

发表于:2015-12-17 09:47

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:不详    来源:51testing软件测试网采编

  在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();
  }
  }

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号