一、基于XML的装配
两种基于XML的装配方式
在基于XML的装配就是读取XML配置文件中的信息完成依赖注入,Spring容器提供了两种基于XML的装配方式,属性setter方法注入和构造方法注入。下面分别对这两种装配方式进行介绍。
a.属性setter方法注入
属性setter方法注入要求一个Bean必须满足以下两点要求。
(1)Bean类必须提供一个默认的无参构造方法。
(2)Bean类必须为需要注入的属性提供对应的setter方法。
b.构造方法注入
使用构造方法注入时,在配置文件里,需要使用<bean>元素的子元素<constructor-arg>来定义构造方法的参数,例如,可以使用其value属性(或子元素)来设置该参数的值。
二、基于注解的装配
XML与注解装配的比较
在Spring中,使用XML配置文件可以实现Bean的装配工作,但在实际开发中如果Bean的数量较多,会导致XML配置文件过于臃肿,给后期维护和升级带来一定的困难。为解决此问题,Spring提供了注解,通过注解也可以实现Bean的装配。
Spring的常用注解
| 注解 | 描述 | 
| @Component | 指定一个普通的Bean,可以作用在任何层次。 | 
| @Controller | 指定一个控制器组件Bean,用于将控制层的类标识为Spring中的Bean, 功能上等同于@Component。 | 
| @Service | 指定一个业务逻辑组件Bean,用于将业务逻辑层的类标识为Spring中的Bean, 功能上等同于@Component。 | 
| @Repository | 指定一个数据访问组件Bean,用于将数据访问层的类标识为Spring 中的Bean, 功能上等同于@Component。 | 
| @Scope | 指定Bean实例的作用域。 | 
| @Value | 指定Bean实例的注入值。 | 
| 注解 | 描述 | 
| @Autowired | 指定要自动装配的对象。 | 
| @Resource | 指定要注入的对象。 | 
| @Qualifier | 指定要自动装配的对象名称,通常与@Autowired联合使用。 | 
| @PostConstruct | 指定Bean实例完成初始化后调用的方法。 | 
| @PreDestroy | 指定Bean实例销毁前调用的方法。 | 
下面通过案例演示如何使用注解来装配Bean,具体实现步骤如下。
1、导入依赖:在项目chapter07的pom.xml文件中导入spring-aop-5.2.8.RELEASE.jar依赖包,导入代码如下所示。
<dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>5.2.8.RELEASE</version>
 </dependency>
2、XML配置文件:创建applicationContext.xml,在该文件中引入Context约束并启动Bean的自动扫描功能。
<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
  http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.mac" />
</beans>
3、定义实体类:新建entity包,在entity包下创建User实体类。
@Component("user")
@Scope("singleton")
public class User {
    @Value("1")
    private int id;
    @Value("张三")
    private String name;
    @Value("123")
    private String password;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String toString(){
        return "id="+id+",name="+name+",password="+password;
    }
}4、定义dao层:创建UserDao接口作为数据访问层接口,并在UserDao接口中声明save()方法,用于查询User实体的对象信息。
package com.mac.dao;
public interface UserDao {
    public void save();
}
5、实现dao层: 创建UserDaoImpl作为UserDao的实现类,并在UserDaoImpl类中实现UserDao接口中的save()方法。
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void save(){
        ApplicationContext applicationContext=new 
              ClassPathXmlApplicationContext("applicationContext.xml");
        User user=(User) applicationContext.getBean("user");
        System.out.println(user);
        System.out.println("执行UserDaoImpl.save()");
    }
}
6、定义service层:创建UserService接口作为业务逻辑层接口,并在UserService接口中定义save()方法。
package com.mac.service;
public interface UserService {
    public void save();
}
7、实现service层:创建UserServiceImpl作为UserService的实现类,并在UserServiceImpl类中实现UserService接口中的save()方法。
@Service("userService")
public class UserServiceImpl implements UserService {
        //使用@Resource注解注入UserDao
        @Resource(name="userDao")
        private UserDao userDao;
        public void save(){
            this.userDao.save();
            System.out.println("执行UserServiceImpl.save()");
        }
}
8、定义controller层: 创建UserController类作为控制层。
@Controller
public class UserController {
    //使用@Resource注解注入UserService
    @Resource(name="userService")
    private UserService userService;
    public void save(){
        this.userService.save();
        System.out.println("执行UserController.save()");
    }
}
9、定义测试类:创建测试类AnnotationTest,在该类中编写测试代码,通过Spring容器加载配置文件并获取UserController实例,然后调用实例中的save()方法。
public class AnnotationTest {
    public static void main(String[] args){
        ApplicationContext applicationContext=new 
             ClassPathXmlApplicationContext("applicationContext.xml");
        UserController usercontroller=(UserController) 
             applicationContext.getBean("userController");
        usercontroller.save();
    }
}
10、查看运行结果:在IDEA中启动AnnotationTest类,控制台会输出结果。

三、自动装配
Spring的<bean>元素中包含一个autowire属性,可以通过设置autowire属性的值实现Bean的自动装配。
autowire属性的值
| 属性值 | 描述 | 
| default(默认值) | 由<bean>的上级元素<beans>的default-autowire属性值确定。 | 
| byName | 根据<bean>元素id属性的值自动装配。 | 
| byType | 根据<bean>元素的数据类型(Type)自动装配,如果一个Bean的数据类型, 兼容另一个Bean中的数据类型,则自动装配。 | 
| constructor | 根据构造函数参数的数据类型,进行byType模式的自动装配。 | 
| no | 默认值,不使用自动装配,Bean依赖必须通过<ref>元素或ref属性定义。 | 


















![[RocketMQ] Broker CommitLogDispatcher 异步构建ConsumeQueue和IndexFile源码解析 (十四)](https://img-blog.csdnimg.cn/5390a81d646040c9996c093700e7fa86.png)
