一. 基于注解配置Bean
1. 自动装配
1. 自动装配的概念
- 手动装配: 以value或ref的方式明确指定属性值都是手动装配。
- 自动装配:根据指定的装配规则,不需要明确指定, Spring自动将匹配的属性值注入bean中。
2. 装配模式
-
手动
<bean id="cat" class="com.hjf.pojo.Cat"> <property name="name" value="猫"/> </bean> <bean id="dog" class="com.hjf.pojo.Dog"> <property name="name" value="狗" /> </bean> <bean id="people1" class="com.hjf.pojo.People"> <property name="name" value="张三" /> <property name="dog" ref="dog" /> <property name="cat" ref="cat" /> </bean>
-
根据类型自动装配:将类型匹配的bean作为属性注入到另一个bean中。若IOC容器中有多个与目标bean类型一致的bean,Spring将无法判定哪个bean最合适该属性,所以不能执行自动装配
<bean id="cat" class="com.hjf.pojo.Cat"> <property name="name" value="猫"/> </bean> <bean id="dog" class="com.hjf.pojo.Dog"> <property name="name" value="狗" /> </bean> <!-- byType: 会自动在容器上下文查找和自己对象类型相同的bean 将上文中声明的cat和dog根据其类型, 自动赋值给people相同的属性 --> <bean id="people2" class="com.hjf.pojo.People" autowire="byType"> <property name="name" value="张三" /> </bean>
-
根据名称自动装配:必须将目标bean的id和属性的set方法的参数名一致[唯一]
<bean id="cat" class="com.hjf.pojo.Cat"> <property name="name" value="猫"/> </bean> <bean id="dog" class="com.hjf.pojo.Dog"> <property name="name" value="狗" /> </bean> <!--byName: 会自动在容器上下文查找和自己对象set方法后面的值对应的bean的beanId--> <bean id="people3" class="com.hjf.pojo.People" autowire="byName"> <property name="name" value="张三" /> </bean>
-
通过构造器自动装配:当bean中存在多个构造器时,此种自动装配方式将会很复杂。不推荐使用。
2. 通过注解配置bean
1. 前提
- 导入context约束
- 配置注解的支持
2. @Autowire
可以在属性上个使用,也可以在set上使用
-
代码
@Data @AllArgsConstructor @NoArgsConstructor public class People { private String name; @Autowired private Cat cat; // @Autowired private Dog dog; }
-
说明
@Autowired(required = false), 说明这个对象可以为null, 否则不允许为空
@Resource: 先通过id查找, 再通过类型查找, 如果都没有找到才报错
二. 使用注解开发
1. 常见注解
- @Autowired: 自动装配通过类型. 名字
如果AutoWired不能唯一自动装配上属性, 则需要通过 - @Qualifier(value=“XXX”)
- @Nullable: 字段标记了这个注解, 说明这个注解可以为null
- @Resource: 自动装配通过名字, 类型
- @Component: 组件, 放在类上, 说明这个类被Spring管理了, 就是bean
2. @value: 属性注入:
-
案例
public class People { @Value("张三") private String name; @Autowired private Cat cat; @Autowired private Dog dog; }
3. @Component: 组件
1. 说明
@Component有几个衍生注解,会按照web开发中,mvc架构中分层。
- dao (@Repository)
- service(@Service)
- controller(@Controller)
这四个注解功能一样的,都是代表将某个类注册到容器中
2. 案例
-
配置文件
<!--注解驱动--> <context:annotation-config /> <!--引入component的扫描组件 --> <!--扫描指定包, 这个包中的注解就会生效--> <context:component-scan base-package="com.hjf.pojo" />
-
实体类
// 等价于: <bean id="people6" class="com.hjf.pojo.People"/> @Component("people6") public class People { @Value("张三") private String name; @Autowired private Cat cat; @Autowired private Dog dog; }
@Data // 等价于: <bean id="cat" class="com.hjf.pojo.Cat"/> @Component("cat") public class Cat { @Value("喵喵喵") private String name; }
@Data // 等价于: <bean id="dog" class="com.hjf.pojo.Dog"/> @Component("dog") public class Dog { @Value("汪汪汪") private String name; }
三. Java方式配置Spring
1. 说明
- @Configuration: 也是@Component, 注册到容器中
- @Import: 导入其他的配置文件
- @ComponentScan: 扫描指定的包
- 重点
@Bean public People getPeople(){ return new People(); }
- 相当于配置文件中的一个bean
2. 案例
-
Java配置文件
// 这个也会被spring容器托管,注册到容器中,因为他本来就是一个@Component @Configuration // 导入其他配置文件 @Import(MyConfig2.class) /** 扫描指定包, 这个包中的注解就会生效 相当于: <context:component-scan base-package="com.hjf.pojo" /> */ @ComponentScan("com.hjf.pojo") public class MyConfig { // 注册一个bean, 相当于我们之前写的一个bean标签 // 这个方法的名字, 就相当于bean标签中的id属性 // 这个方法的返回值, 就相当于bean标签中的class属性 @Bean public People getPeople(){ return new People(); } @Bean public Cat getCat(){ return new Cat(); } @Bean public Dog getDog(){ return new Dog(); } }
-
测试
@Test public void test01(){ // Java配置文件时: AnnotationConfigApplicationContext // XML配置文件时: ClassPathXmlApplicationContext ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); People people = context.getBean("people", People.class); System.out.println(people); }