首页  >  文章  >  Java  >  Spring 常用的三种注入方式

Spring 常用的三种注入方式

Guanhui
Guanhui原创
2020-06-02 11:08:155569浏览

Spring 常用的三种注入方式

Spring 常用的三种注入方式

1、构造方法,采用反射的方式,通过构造方法来完成注入。

先简单了解一下测试项目的结构,用maven构建的,四个包:

  • entity:存储实体,里面只有一个User类

  • dao:数据访问,一个接口,两个实现类

  • service:服务层,一个接口,一个实现类,实现类依赖于IUserDao

  • test:测试包

在spring的配置文件中注册UserService,将UserDaoJdbc通过constructor-arg标签注入到UserService的某个有参数的构造方法

<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
  <constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>

如果只有一个有参数的构造方法并且参数类型与注入的bean的类型匹配,那就会注入到该构造方法中。

public class UserService implements IUserService {
  private IUserDao userDao;
  
  public UserService(IUserDao userDao) {
    this.userDao = userDao;
  }
  
  public void loginUser() {
    userDao.loginUser();
  }
}
@Test
public void testDI() {
  ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  // 获取bean对象
  UserService userService = ac.getBean(UserService.class, "userService");
  // 模拟用户登录
  userService.loginUser();
}

测试打印结果:jdbc-登录成功

注:模拟用户登录的loginUser方法其实只是打印了一条输出语句,jdbc实现的类输出的是:jdbc-登录成功,mybatis实现的类输出的是:mybatis-登录成功。

2、setter,也是采用反射的方式,不过是通过setter来完成注入。

配置文件如下:

<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
  <!-- 写法一 -->
  <!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
  <!-- 写法二 -->
  <property name="userDao" ref="userDaoMyBatis"></property>
</bean>
<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>

注:上面这两种写法都可以,spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上"set"构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入。

切记:name属性值与类中的成员变量名以及set方法的参数名都无关,只与对应的set方法名有关,下面的这种写法是可以运行成功的

public class UserService implements IUserService {
  private IUserDao userDao1;
  
  public void setUserDao(IUserDao userDao1) {
    this.userDao1 = userDao1;
  }
  
  public void loginUser() {
    userDao1.loginUser();
  }
}

还有一点需要注意:如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错。

3、基于注解,常用的有“@Autowried”和“@Resource”。

示例代码

// candidateBeans 为上一步通过类型匹配到的多个bean,该 Map 中至少有两个元素。
protected String determineAutowireCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {
    //  requiredType 为匹配到的接口的类型
   Class<?> requiredType = descriptor.getDependencyType();
   // 1. 先找 Bean 上有@Primary 注解的,有则直接返回
   String primaryCandidate = this.determinePrimaryCandidate(candidateBeans, requiredType);
   if (primaryCandidate != null) {
       return primaryCandidate;
   } else {
       // 2.再找 Bean 上有 @Order,@PriorityOrder 注解的,有则返回
       String priorityCandidate = this.determineHighestPriorityCandidate(candidateBeans, requiredType);
       if (priorityCandidate != null) {
           return priorityCandidate;
       } else {
           Iterator var6 = candidateBeans.entrySet().iterator();
           String candidateBeanName;
           Object beanInstance;
           do {
               if (!var6.hasNext()) {
                   return null;
               }
               // 3. 再找 bean 的名称匹配的
               Entry<String, Object> entry = (Entry)var6.next();
               candidateBeanName = (String)entry.getKey();
               beanInstance = entry.getValue();
           } while(!this.resolvableDependencies.values().contains(beanInstance) && !this.matchesBeanName(candidateBeanName, descriptor.getDependencyName()));
           return candidateBeanName;
       }
   }
}

推荐教程:《Java教程

以上是Spring 常用的三种注入方式的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn