Bean的自动装配
自动装配式spring满足bean依赖的一种方式
spring会在上下文中进行寻找,并自动给bean装配属性
在spring中由三种装配方式
- 在xml中显示配置
- 在Java中显示配置
- 隐式的自动装配bean 【重要】
测试
<bean id="cat" class="com.wjq.pojo.Cat"/>
<bean id="dog" class="com.wjq.pojo.Dog"/>
<bean id="people" class="com.wjq.pojo.People">
<property name="name" value="www"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
ByName
public void setDog1(Dog dog) {
this.dog = dog;
}
public void setCat1(Cat cat) {
this.cat = cat;
}
<bean id="cat1" class="com.wjq.pojo.Cat"/>
<bean id="dog1" class="com.wjq.pojo.Dog"/>
<!-- byName根据bean id的名字在对应的set方法中查找,当同名时查找成功-->
<bean id="people" class="com.wjq.pojo.People" autowire="byName">
<property name="name" value="www"/>
</bean>
ByType
byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
<bean class="com.wjq.pojo.Cat"/>
<bean class="com.wjq.pojo.Dog"/>
<!-- byType根据对应属性对象的类型进行查找-->
<bean id="people" class="com.wjq.pojo.People" autowire="byType">
<property name="name" value="www"/>
</bean>
小结:
byName:必须保证所有bean的id是唯一的,并且这个bean要和需要自动注入的set方法的值一致(一个类只能创建一个对象)
byType:要保证所有bean的class是唯一的,并且这个bean要和需要自动注入的属性的类型一致
使用注解实现自动装配
要使用注解须知:
-
导入约束:context
-
配置注解的支持:context:annotation-config/
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
@Autowired
直接在属性上使用,或者set(),可以省略set(),前提是自动装配的属性在Spring容器中,且符合byName
@Nullable标记表示此字段可以为null
public @interface Autowired {
boolean required() default true;
}
//如果显示定义了required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Dog dog;
如果使用@Autowired自动装配环境比较复杂,一个@Autowired无法实现可以使用@Qualifier(value = “xxx”)配合@Autowired使唯一的一个bean对象注入
required=true代表字段cat1必须要注入值,也即是说在Spring容器中根据类型找不到对应的bean,那就会报异常;required=false意味着在Spring容器中根据类型找不到对应的的bean,就会把该字段设为null。
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Resource
先根据名字匹配,再根据类型匹配,属于java而不是Spring
@Resource(name = "cat1")
private Cat cat;
小结:
@Autowired和@Resource都可以实现自动装配
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false
@Autowire注解和@Resource都可以标注在字段或属性的set()上。
@Resource先是通过byName如果没有找到,可以再通过byType,如果两个都找不着,就会报错
使用注解开发
-
首先保证aop包的导入,spring-MVC中含有aop依赖
-
其次是context
applicatio.xml
<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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<!-- 可以扫描此包下的注解-->
<context:component-scan base-package="com.wjq.pojo"/>
</beans>
-
bean
-
属性如何注入
//表示组件 相当于<bean id="user" class="com.wjq.pojo.User"> </bean> @Component public class User { // public String name = "wjq"; //赋值 相当于<property name="name" value="wjq"/> // @Value("wjq") public String name; @Value("wjq") public void setName(String name) { this.name = name; } }
-
衍生的注入
controller:@Controller
dao:@Repository
service:@Service
-
自动装配
@Autowired @Qualifier(value = "cat1") private Cat cat; @Resource(name = "cat1") private Cat cat;
-
作用域
@Scope("singleton")
-
小结
XML和注解:
XML:相对来说比较复杂,但是功能强大
注解:不是自己的类使用不了,维护复杂
XML和注解的搭配:
用XML来实现bean,用注解实现注入
使用java的方式配置spring
User类
public class User {
@Value("wjq1")//赋值
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
config类
@Configuration//本质@Component,因此可以看出由spring托管,此注解相当于配置文件
//@ComponentScan("com.wjq.pojo")
public class Config {
// User 相当于 class(xml)
// user 相当于 id(xml)
@Bean//注册一个bean,相当于之前写的bean标签
public User user(){
return new User();
}
}
test类
public class MyTest {
public static void main(String[] args) {
//用来加载config类,相当于之前的CPX
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
User user = context.getBean("user", User.class);
System.out.println(user.getName());
}
}