【SpringBoot_ANNOTATIONS】自动装配 03 方法 构造器位置的自动装配

自动装配 03 方法 构造器位置的自动装配

@Autowired的位置:构造器 方法 参数 属性 都是从容器中获取参数的值

  1. 方法上:Spring容器创建当前对象就会调用此方法 完成赋值
    • 方法使用的参数 自定义类型就会从ioc容器中获取
  2. 构造器上: 构造器要用的组件都是从容器中获取
    • 若bean中只有一个有参构造方法,@Autowired注解可以省掉,默认会调用这个参数位置的组件还是会从ioc容器获取
  3. 参数上:@Bean + 方法参数:默认不写@Autowired ,也能自动装配 也是从ioc容器中获取

Boss.java

@Component
public class Boss {

    private Car car;

    public Car getCar() {
        return car;
    }

    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss{" +
                "car=" + car +
                '}';
    }
}

Car.java

/**
 * 生命周期测试
 * 自动装配测试
 */
@Component
public class Car {
    public Car() {
        System.out.println("car constructor ...");
    }

    /**
     * 做初始化方法
     * 初始化方法不可以有参数 但可以抛异常
     */
    public void init() {
        System.out.println("car init ...");
    }

    /**
     * 做销毁方法
     * 销毁方法不可以有参数 但可以抛异常
     */
    public void destroy() {
        System.out.println("car destroy ...");
    }
}

配置类

@Configuration
@ComponentScan(value = {"com.example.annotations.service","com.example.annotations.dao","com.example.annotations.controller","com.example.annotations.bean"})
public class MainConfig4Autowire {

}

测试:

    @Test
    void autowiredTest(){
        //配置类测试
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig4Autowire.class);
        System.out.println("容器创建完毕");
        //获取bean
        System.out.println("准备获取bean");
        Boss boss = applicationContext.getBean(Boss.class);
        Car car = applicationContext.getBean(Car.class);
        System.out.println(boss.toString());
        System.out.println(car.toString());
        System.out.println("获取完毕");
        //关闭容器
        applicationContext.close();
        System.out.println("容器已关闭");
    }

在这里插入图片描述

@Bean + 方法参数

@Component
public class Boss {

    private Car car;

    public Boss(Car car) {
        System.out.println("构造方法注入");
        this.car = car;

    }

    public Car getCar() {
        return car;
    }

//    @Autowired
    public void setCar(Car car) {
        System.out.println("setter注入");
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss{" +
                "car=" + car +
                '}';
    }
}

运行测试之后可看到有相应输出

### 实现 SSM 框架中的自动装配Spring 中,自动装配(autowiring)是一种依赖注入的方式,它允许容器管理对象之间的关系而无需显式的 setter 或者构造器注入。为了使 SSM 框架能够支持自动装配功能,在配置文件中需要启用组件扫描以及定义相应的 Bean。 #### 配置 `applicationContext.xml` 文件来启动组件扫描并设置包路径: ```xml <context:component-scan base-package="com.example.ssm"/> ``` 此行代码会告诉 Spring 容器去查找指定基础包及其子包下带有特定注解的类,并将其注册为 SpringBean[^1]。 对于 MyBatis 和 Spring 整合部分,则可以通过如下方式完成 Mapper 接口的自动发现与映射: ```xml <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.ssm.mapper"/> </bean> ``` 上述 XML 片段用于指示 MyBatis-Spring 扩展库寻找给定的基础包内的所有接口作为 mapper 并创建对应的代理实例。 接下来展示一个简单的例子说明如何利用这些特性简化开发过程: 假设有一个名为 `UserMapper.java` 的 DAO 层接口负责处理数据库操作;还有一个服务层逻辑实现类 `UserService.java`; 最后是一个控制器 `UserController.java`. - **DAO Layer (MyBatis)**: ```java package com.example.ssm.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; @Repository // 将该类标记为持久化层组件 public interface UserMapper { @Select("SELECT * FROM users WHERE id=#{id}") User getUserById(int id); @Insert("INSERT INTO users(name,email,password) VALUES(#{name}, #{email}, #{password})") void insertUser(User user); } ``` - **Service Layer**: ```java package com.example.ssm.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service // 注册成业务逻辑层的服务组件 public class UserService { private final UserMapper userMapper; @Autowired // 自动注入已存在的 bean 到当前属性上 public UserService(UserMapper userMapper){ this.userMapper = userMapper; } public User findUserById(Integer userId){ return userMapper.getUserById(userId); } } ``` - **Web Controller**: ```java package com.example.ssm.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController // 组合了@Controller和@ResponseBody两个注解的作用 @RequestMapping("/users") public class UserController { private final UserService userService; @Autowired // 构造函数注入优于字段级或setter方法级别的注入 public UserController(UserService userService){ this.userService = userService; } @GetMapping("/{userId}") public ResponseEntity<User> getUser(@PathVariable Integer userId){ try{ User user = userService.findUserById(userId); if(user != null){ return new ResponseEntity<>(user, HttpStatus.OK); }else{ throw new ResourceNotFoundException(); } }catch(Exception e){ logger.error(e.getMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } } ``` 通过以上配置和编码实践可以显著减少样板代码的数量,提高项目的可维护性和扩展性。值得注意的是,在实际项目中应当遵循最佳实践原则合理运用自动装配机制,比如优先考虑基于类型的构造参数注入而非字段级别或者 Setter 方法级别的注入形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值