SpringDI(依赖注入)之注解配置

    技术2025-03-23  20

    前言

    ​ 通过xml配置方式的形式,可以实现依赖注入,但是也能够发现xml配置方式的弊端,就是太繁琐,所以我们学习使用注解进行依赖注入,相比起xml来说,就简化了很多。

    注解介绍

    @Autowired依赖注入

    使用位置:作用于要注入Bean的类成员变量上,也可以作用于方法的形参上

    作用:自动按照类型注入, 只要spring容器中有与要注入数据的类型相配的Bean对象, 数据就能够自动注入成功,如果没有或有多个同类型的Bean时,就会出现报错。

    使用实例

    @Autowired private UserDao userDao;

    @qualifier依赖注入

    使用位置:此注解不能单独使用,要结合@Autowired使用,作用于要注入Bean的类成员变量上。

    作用:配置@Autowired注解使用,在按照类型注入的基础上,再根据Bean的id进行注入,这样就能够解决Spring容器中有多个相同类型的Bean时,出现的注入异常。

    使用实例

    @Qualifier("userDaoImpl") @Autowired private UserDao userDao;

    @Resource依赖注入

    使用位置:作用于要注入Bean的类成员变量上。

    作用:此注解的作用是指定按照id注入,还是按照类型注入;当只是用注解时,默认按照id进行注入。

    使用实例

    @Resource //默认按照 id 为 userDao的bean实例注入,此时的id就是变量的变量名 @Resource(name="userDao") //按照 id 为 userDao的bean实例注入 @Resource(type="UserDao") //按照 类型 为 UserDao的bean实例注入 @Resource private UserDao userDao;

    @Primary控制bean的优先使用

    使用位置:作用于类上

    作用:当spring中有两个或多个相同的bean的时候,可以使用此注解,在进行依赖注入的时候,指定优先使用的bean。

    使用实例

    接口

    public interface UserDao { }

    接口实现类1

    @Component public class UserDaoImpl1 implements UserDao { }

    接口实现类2

    @Component public class UserDaoImpl2 implements UserDao { }

    进行依赖注入的类

    @Component public class Demo { //为此属性注入类型为UserDao的bean @Autowired public UserDao userDao; }

    测试类

    public class Test { public static void main(String[] args) { //创建spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Demo demo = context.getBean(Demo.class); System.out.println(demo); } }

    注意执行以上代码会报错,说在spring容器中找到两个类型为UserDao的bean(因为两个实现类都实现了UserDao接口),所以在给userDao属性进行依赖注入的时候,spring不知道使用哪一个,造成报错

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itheima.dao.UserDao' available: expected single matching bean but found 2: userDaoImpl1,userDaoImpl2

    此时就可以在想优先使用的类上添加@Primary注解,指定优先使用的bean

    @Component @Primary public class UserDaoImpl2 implements UserDao { }

    执行结果

    @PropertySource加载外部配置文件

    作用位置:作用于类上

    作用:加载外部资源文件,配合@Value(${propertyName})使用。

    使用实例

    properties配置文件

    name="shangsan" age=32

    学生实体类

    @Repository @PropertySource("classpath:db.properties") public class Student implements Serializable { @Value("${name}") private String name; @Value("${age}") private Integer age; //...get set省略... }

    测试类

    public class App { public static void main(String[] args) { //创建spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取Bean Student student = context.getBean(Student.class); System.out.println(student); } }

    结果

    @Import与@Bean 控制spring加载bean

    @import

    使用位置:作用于spring配置类上作用:直接导入一个bean,注入到Spring容器中,一般在使用注解的spring配置类中使用。

    @Bean

    使用位置:作用于方法上将所在方法的返回值作为bean存入spring容器中,bean的id就是方法名。

    使用实例

    数据库连接池配置

    /** * 德鲁伊连接池配置 */ public class DataSourceConfig { @Bean("dataSource") public DataSource getDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql//192.168.242.130:3306/db"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; } }

    Spring配置类

    //标识此类为spring配置类 @Configuration //指定要扫描的包,只有指定包下的注解才能被spring解析 @ComponentScan("com.itheima") //引入bean存入spring容器 @Import(DataSourceConfig.class) public class SpringConfig { }

    测试类

    public class Test { public static void main(String[] args) { //创建spring容器, 通过配置类的方式创建spring容器,要使用AnnotationConfigApplicationContext类,指定配置类的字节码对象 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); //获取bean DataSource dataSource = context.getBean(DataSource.class); System.out.println(dataSource); } }

    @DependsOn 类依赖

    作用位置:作用于类上。

    作用:用于指定某个类依赖于某个类,当spring加载的时候,就会优先加载被依赖的类,从而创建bean。

    使用实例

    Student.java

    @Repository public class Student implements Serializable { public Student() { System.out.println("student类加载了"); } }

    User.java

    @Repository //当前user依赖于student,所以创建会先加载student @DependsOn("student") public class User { public User() { System.out.println("user类加载了"); } }

    测试类

    public class App { public static void main(String[] args) { //创建spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); } }

    结果

    @Order 控制加载bean的优先级

    作用位置:作用于类上

    作用:控制spring加载类的先后顺序,指定的数值越小,越先加载 @Order(1)比@Order(2)先加载,@Order(-1)最先加载。

    @Lazy 延迟加载

    作用位置:作用于类上作用:延迟加载,创建spring容器的时候不加载该类,等到使用的时候才加载。

    ​ 要在Spring配置文件中配置组件扫描器

    <?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 http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置spring组件扫描器 base-package:指定要扫描的包,只要该包下的注解才能被Spring解析 --> <context:component-scan base-package="com.my"/> </beans>
    Processed: 0.009, SQL: 9