一. 基于注解配置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);
}