Spring中bean的自动装配
- 自动装配是Spring满足bean依赖一种方式!
- Spring会在上下文中自动寻找,并自动给bean装配属性!
在Spring中有三种装配的方式:
- 在xml中显式的配置;
- 在java中显式配置;
- 隐式的自动装配bean【重要】
1.搭建环境
xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.sangyu.pojo.Dog"></bean>
<bean id="Cat" class="com.sangyu.pojo.Cat"></bean>
<bean id="person" class="com.sangyu.pojo.Person">
<property name="name" value="桑榆"/>
<property name="cat" ref="Cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
pojo:
一个人有两个宠物
package com.sangyu.pojo;
/**
* @author sangYu
* @date 2023/2/25
*/
public class Cat {
public void play(){
System.out.println("catPlay..................");
}
}
package com.sangyu.pojo;
/**
* @author sangYu
* @date 2023/2/25
*/
public class Dog {
public void play(){
System.out.println("dogPlay..................");
}
}
package com.sangyu.pojo;
/**
* @author sangYu
* @date 2023/2/25
*/
public class Person {
private String name;
private Dog dog;
private Cat cat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", dog=" + dog +
", cat=" + cat +
'}';
}
}
Test:
package com.sangyu;
import com.sangyu.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author sangYu
* @date 2023/2/25
*/
public class Test {
@org.junit.Test
public void Test01(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Person person = applicationContext.getBean("person", Person.class);
person.getCat().play();
person.getDog().play();
}
}
2.ByName自动装配
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id
<bean id="dog" class="com.sangyu.pojo.Dog"></bean>
<bean id="cat" class="com.sangyu.pojo.Cat"></bean>
<bean id="person" class="com.sangyu.pojo.Person" autowire="byName">
<property name="name" value="桑榆"/>
</bean>
3.ByType自动装配
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
<bean class="com.sangyu.pojo.Dog"></bean>
<bean class="com.sangyu.pojo.Cat"></bean>
<bean id="person" class="com.sangyu.pojo.Person" autowire="byType">
<property name="name" value="桑榆"/>
</bean>
小结:
- ByName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
- ByType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
4.注解装配
1.导入约束
2.配置注解支持
<?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">
<context:annotation-config/>
</beans>
@Autowired
直接在属性上使用即可,也可以在set方法上使用.
使用Autowired我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字ByName!
测试:
package com.sangyu.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* @author sangYu
* @date 2023/2/25
*/
public class Person {
private String name;
@Autowired
@Qualifier("dog1")
private Dog dog;
@Autowired
@Qualifier("cat1")
private Cat cat;
}
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
@Resource
public class People {
@Resource
private Cat cat;
@Resource
private Dog dog;
}
小结:
@Resource和@Autowired的区别:
都是用来自动装配的,都可以放在属性字段上
@Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
@Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
执行顺序不同:@Autowired通过byType的方式实现。
使用注解开发
1.环境配置
要使用注解开发,首先要保证aop的包导入了
使用注解需要导入约束,配置注解的支持!
<?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">
<context:component-scan base-package="com.sangyu"/>
<context:annotation-config/>
</beans>
2.bean
我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!
1、配置扫描哪些包下的注解
<!--指定注解扫描包-->
<context:component-scan base-package="com.sangyu"/>
2、在指定包下编写类,增加注解
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
public String name = "桑榆";
}
3、测试
@Test
public void test(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("appplicationContext.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user.name);
}
3.属性注入
使用注解注入属性
1、可以不用提供set方法,直接在直接名上添加@value(“值”)
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
@Value("桑榆")
// 相当于配置文件中 <property name="name" value="桑榆"/>
public String name;
}
2、如果提供了set方法,在set方法上添加@value(“值”);
@Component("user")
public class User {
public String name;
@Value("桑榆")
public void setName(String name) {
this.name = name;
}
}
4.衍生注解
@Component三个衍生注解
为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。
@Controller:web层
@Service:service层
@Repository:dao层
写上这些注解,就相当于将这个类交给Spring管理装配了!
5.作用域
@scope
singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Controller("user")
@Scope("prototype")
public class User {
@Value("桑榆")
public String name;
}
6.小结
XML与注解比较
-
XML可以适用任何场景 ,结构清晰,维护方便
-
注解不是自己提供的类使用不了,开发简单方便
-
xml与注解整合开发 :推荐最佳实践
-
xml管理Bean
-
注解完成属性注入
-
使用过程中, 可以不用扫描,扫描是为了类上的注解
<context:annotation-config/>
作用:
-
进行注解驱动注册,从而使注解生效
-
用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
-
如果不扫描包,就需要手动配置bean
-
如果不加注解驱动,则注入的值为null!
7.常用注解
@Autowired:用在属性上,表示自动装配该属性
@Qualifier:与Autowired配套使用,用于映射bean的id名称到类的属性上
@Nullable:表示该值可以未null
@Resource:Java原生的自动装配注解 带有name、type属性
@Component【pojo层】:组件、放在类上,表示这个类注入到Spring容器中,由spring管理
@value:可以放在属性上和set方法上,表示为这个属性赋值
等价于
@Component的衍生注解:
-
@Respository 【Dao层】
-
@Services【service层】
-
@Controller 【controller层】
@Scope:作用域
@Import:引入其他配置类
@Configuration:表明该类为配置类
@ComponentSan:扫描包,被扫描包下的注解可生效
@Bean:等同于bean标签的配置