@Resource注解实现自动注入(反射)

80 min read
  • 默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
  • 如果属性字段名称未找到,则会通过类型(Class类型)查找
  • 属性可以提供set方法,也可以不提供set方法
  • 注解可以声明在属性级别 或 set方法级别
  • 可以设置name属性,name属性值必须与bean标签的id属性值一致;如果设置了name属性值,就只会按照name属性值查找bean对象
  • 当注入接口时,如果接口只有一个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <beans>
    		
        <!--   开启包扫描     -->
        <context:component-scan base-package="org.example"/>

        <bean id="userService" class="org.example.UserService"/>
        <bean id="userDao" class="org.example.UserDao"/>
    </beans>
</beans>
  1. 默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)

    /**
     * @Resource注解实现自动注入(反射)
     *  默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
     */
    public class UserService {
    
        @Resource
        private UserDao userDao; // 属性字段的名称与bean标签的id属性值相等
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test() {
            // 调用UserDao的方法
            userDao.test();
        }
    }
    
  2. 如果属性字段名称未找到,则会通过类型(Class类型)查找

    /**
     * @Resource注解实现自动注入(反射)
     *   如果属性字段名称未找到,则会通过类型(Class类型)查找
     */
    public class UserService {
    
        @Resource
        private UserDao ud; // 当在配置文件中属性字段名(ud)未找到,则会查找对应的class(UserDao类型)
    
        public void setUd(UserDao ud) {
            this.ud = ud;
        }
    
        public void test() {
            // 调用UserDao的方法
            ud.test();
        }
    }
    
  3. 属性可以提供set方法,也可以不提供set方法

    /**
     * @Resource注解实现自动注入(反射)
     *   属性可以提供set方法,也可以不提供set方法
     */
    public class UserService {
    
        @Resource
        private UserDao userDao; // 不提供set方法
    
    
        public void test() {
            // 调用UserDao的方法
            userDao.test();
        }
    }
    
  4. 注解可以声明在属性级别 或 set方法级别

    /**
     * @Resource注解实现自动注入(反射)
     *   注解可以声明在属性级别 或 set方法级别
     */
    public class UserService {
    
        private UserDao userDao;
    
        @Resource // 注解也可设置在set方法上
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test() {
            // 调用UserDao的方法
            userDao.test();
        }
    }
    
  5. 可以设置name属性,name属性值必须与bean标签的id属性值一致;如果设置了name属性值,就只会按照name属性值查找bean对象

    /**
     * @Resource注解实现自动注入(反射)
     *   可以设置name属性,name属性值必须与bean的id属性值一致;
     *   如果设置了name属性值,就只会按照name属性值查找bean对象
     */
    public class UserService {
    
        @Resource(name = "userDao") // name属性值与配置文件中bean标签的id属性值一致
        private UserDao ud;
    
    
        public void test() {
            // 调用UserDao的方法
            ud.test();
        }
    }
    
  6. 当注入接口时,如果接口只有一个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的bean对象

    定义接口类 IUserDao.java

    package com.xxxx.dao;
    
    /**
     * 定义接口类
     */
    public interface IUserDao {
        public void test();
    }
    

    定义接口实现类 UserDao01.java

    package com.xxxx.dao;
    
    /**
     * 接口实现类
     */
    public class UserDao01 implements IUserDao {
    
        @Override
        public void test(){
            System.out.println("UserDao01...");
        }
    }
    

    定义接口实现类 UserDao02.java

    package com.xxxx.dao;
    
    /**
     * 接口实现类
     */
    public class UserDao02 implements IUserDao {
    
        @Override
        public void test(){
            System.out.println("UserDao02...");
        }
    }
    

    XML配置文件

    <!--开启自动化装配(注入)-->
    <context:annotation-config/>
    
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
    
    <bean id="userDao01" class="com.xxxx.dao.UserDao01"></bean>
    <bean id="userDao02" class="com.xxxx.dao.UserDao01"></bean>
    

    使用注解 UserService.java

    /**
     * @Resource注解实现自动注入(反射)
     *   当注入接口时,如果接口只有一个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的bean对象
     */
    public class UserService {
    
        @Resource(name = "userDao01") // name属性值与其中一个实现类的bean标签的id属性值一致
        private IUserDao iUserDao; // 注入接口(接口存在多个实现)
    
        public void test() {
            iUserDao.test();
        }
    }