前言
通过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>