java八股文DI

DI

依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象.我们使⽤ @Autowired 这个注解,完成了依赖注⼊的操作.简单来说, 就是把对象取出来放到某个类的属性中

关于依赖注⼊, Spring也给我们提供了三种⽅式:

  1. 属性注⼊(Field Injection)
  2. 构造⽅法注⼊(Constructor Injection)
  3. Setter 注⼊(Setter Injection)

构造器注入

1.构造器注入

java 复制代码
//创建一个水杯类
class Cup{
    public void holdCup(){
        System.out.println("水杯装水");
    }
}
//人喝水,构造器注入
class Person{
    private Cup cup;
    //构造器注入依赖
    public Person(Cup cup){
        this.cup=cup;
    }
    public void drinkWater(){
        cup.holdCup();
        System.out.println("人喝水");
    }
}

Setter方法注入

java 复制代码
class Person {
    private Cup cup;
    
    // Setter方法注入
    public void setCup(Cup cup) {
        this.cup = cup;
    }
    
    public void drinkWater() {
        cup.holdWater();
        System.out.println("喝水");
    }
}

*属性注入(重点)

通过@Autowired,将Service层类注入Controller类中

java 复制代码
@Service
public class UserService {
    public void method(){
        System.out.println("启动UserService类");
    }
}
java 复制代码
@Controller
public class UserController {
    @Autowired
    private  UserService service;

    public void method(){
        System.out.println("启动UserController类");
        service.method();
    }
}
@Autowired存在问题

当同⼀类型存在多个bean时, 使⽤@Autowired会存在问题

java 复制代码
@Data
@Component
class User{
     private String userName;
     private Integer age;

 }
@Component
public class Autowired {
    @Bean
    public User uesr1(){
        User user=new User();
        user.setUserName("zhangsan");
        user.setAge(18);
        return user;
    }
    @Bean
    public User user2(){
        User user=new User();
        user.setUserName("lisi");
        user.setAge(20);
        return user;
    }
}
java 复制代码
@Controller
public class UserController {
    @Autowired
    private  UserService service;

    @Autowired
    private User user;

    public void method(){
        System.out.println("启动UserController类");
        service.method();
        System.out.println(user);
    }
}
Spring提供了以下⼏种解决⽅案:

• @Primary

• @Qualifier

• @Resource

• @Primary:

• @Qualifier:

• @Resource

@Autowird 与 @Resource的区别:

• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解

• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐@Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean.

总结:

属性注⼊

◦ 优点: 简洁,使⽤⽅便;

◦ 缺点:▪ 只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)

▪ 不能注⼊⼀个Final修饰的属性

• 构造函数注⼊(Spring 4.X推荐)

◦ 优点:

▪ 可以注⼊final修饰的属性

▪ 注⼊的对象不会被修改

▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法是在类加载阶段就会执⾏的⽅法.

▪ 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的

◦ 缺点:

▪ 注⼊多个对象时, 代码会⽐较繁琐

• Setter注⼊(Spring 3.X推荐)

◦ 优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊

◦ 缺点:

▪ 不能注⼊⼀个Final修饰的属性

▪ 注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险

相关推荐
代码什么用8 小时前
Spring基础使用
java·后端·spring
Su米苏8 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园8 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁8 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网9 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西9 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨9 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
小卡车5559 小时前
java反射、自定义注解的应用(自定义分页)
java
BLUcoding10 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
yuniko-n10 小时前
【JUC】Lock 和 synchronzied 锁
java