装配Bean方式
一、装配Bean方式汇总
Spring容器负责创建Bean并通过DI来协调对象间关系。
二、自动化装配Bean
实现自动化装配Bean,主要有两步骤:组件扫描和自动装配。
组件扫描(component scanning):Spring 会自动发现应用上下文中所创建的 bean【默认不开启】。
自动装配(autowiring):让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在 Spring 应用上下文中寻找匹配某个 bean 需求的其他 bean【可使用xml和注解两种自动装配实现】。
2.1 组件扫描
Spring默认情况下,组件扫描是不启用的。我们还需要显式配置一下 Spring,从而命令它去寻找带有@Component、@Service注解的类,并为其创建bean。
@Configuration --配置spring容器(应用上下文),将该类注入成Bean对象
@ComponentScan ----在spring中启用组件扫描
public class scanConfig {
}
—由于没有其他配置信息,那么@ComponentScan会默认扫描scanConfig类所在的包及包下的所有子包,查找带@Component、@Service注解的类。
2.2 自动装配Bean—基于xml方式
查看spring4.x的jar文件可以发现,基于xml配置的自动装配Bean有四种模式。
—customer类
public class Customer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
—HotelV1类【default、byName、byType方式】
public class HotelV1 {
private Customer customer;
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Customer getCustomer() {
return customer;
}
public String getName(){
return customer.getName();
}
}
—hotelV2类【constructor方式】
public class HotelV2 {
private Customer customer;
public HotelV2(Customer customer){
this.customer = customer;
}
public String getName(){
return customer.getName();
}
}
–applicationContenxt.xml
<bean id="customer" class="com.wwy.JavaBean.XmlConfig.Customer">
<property name="name" value="wwy"></property>
</bean>
这里就是采用默认方式将Customer类装配成Bean了。接下来,下面是介绍采用四种装配Bean方式,怎么将HotelV1和HotelV2类装配成Bean,且他们依赖了Customer类。
2.2.1 default方式模式
–applicationContenxt.xml
--applicationContenxt.xml
<!--xml自动装配-默认方式装配Bean-->
<bean id="hotelV1" class="com.wwy.JavaBean.XmlConfig.HotelV1">
<property name="customer" ref="customer" />
</bean>
2.2.2 byName方式模式
<!--xml自动装配-byName方式装配Bean-->
<bean id="hotelV1" class="com.wwy.JavaBean.XmlConfig.HotelV1" autowire="byName"></bean>
2.2.3 byType方式模式
<!--xml自动装配-byType方式装配Bean-->
<bean id="hotelV1" class="com.wwy.JavaBean.XmlConfig.HotelV1" autowire="byType"></bean>
2.2.4 constructor方式模式
<!--xml自动装配-constructor方式装配Bean-->
<bean id="hotelV2" class="com.wwy.JavaBean.XmlConfig.HotelV2" autowire="constructor"></bean>
2.3 自动装配Bean—注解方式
注解可以通过构造器、setter方法 以及字段(属性)自动装配bean。
要想注解生效,那么需要xml中配置下
<!--<context:annotation-config />-->
<!-- Spring容器中注册非@controller注解的Bean -->
<context:component-scan base-package="com.wwy.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
—people类
public class People {
private String name;
public People(String name){this.name = name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Xml中将people类和company类都装配成Bean,下面将采用三种方式将people类注入到company类。
2.3.1 构造器方式
在构造器上加入注解即可。
–applicationContenxt.xml
<!--注解自动装配Bean-->
<bean id="people" class="com.wwy.JavaBean.NoteConfig.People">
<!--这里通过property和constructor-arg同时设置一个属性name,最终name的值是property1而不是constructor1-->
<property name="name" value="property1"></property>
<constructor-arg name="name" value="constructor1"></constructor-arg>
</bean>
<bean id="company" class="com.wwy.JavaBean.NoteConfig.Company"></bean>
----company类
public class Company {
private People people;
@Autowired
public Company(People people){
this.people = people;
}
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
}
-----【构造器方式】如果xml中一个类有两个Bean,那该如何装载呢?----此时不能用@Autowired,而用@Qualifier
<bean id="people1" class="com.wwy.JavaBean.NoteConfig.People">
<!--这里通过property和constructor-arg同时设置一个属性name,最终name的值是property1而不是constructor1-->
<property name="name" value="property1"></property>
<constructor-arg name="name" value="constructor1"></constructor-arg>
</bean>
<!--两个bean时,此时用@AutoWired会报错,用@Qualifier才可以-->
<bean id="people2" class="com.wwy.JavaBean.NoteConfig.People">
<property name="name" value="property2"></property>
<constructor-arg name="name" value="constructor2"></constructor-arg>
</bean>
public class Company {
private People people;
@Autowired(required = false)
public Company( @Qualifier("people2") People people ) {
this.people = people;
}
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
}
2.3.2 setter方式
—xml配置
<bean id="people" class="com.wwy.JavaBean.NoteConfig.People">
<!--这里通过property和constructor-arg同时设置一个属性name,最终name的值是property1而不是constructor1-->
<property name="name" value="property1"></property>
<constructor-arg name="name" value="constructor1"></constructor-arg>
</bean>
public class Company {
private People people;
public People getPeople() {
return people;
}
@Autowired
public void setPeople(People people) {
this.people = people;
}
}
-----【setter方式】如果xml中一个类有两个Bean,那该如何装载呢?
<!--注解自动装配Bean-->
<bean id="people1" class="com.wwy.JavaBean.NoteConfig.People">
<!--这里通过property和constructor-arg同时设置一个属性name,最终name的值是property1而不是constructor1-->
<property name="name" value="property1"></property>
<constructor-arg name="name" value="constructor1"></constructor-arg>
</bean>
<!--两个bean时,此时用@AutoWired会报错,用@Qualifier才可以-->
<bean id="people2" class="com.wwy.JavaBean.NoteConfig.People">
<property name="name" value="property2"></property>
<constructor-arg name="name" value="constructor2"></constructor-arg>
</bean>
public class Company {
private People people;
public Company(People people){
this.people = people;
}
public People getPeople() {
return people;
}
@Autowired(required = false)
@Qualifier("people1")
public void setPeople(People people) {
this.people = people;
}
}
2.3.3 字段(属性)方式
–xml配置
<!--注解自动装配Bean-->
<bean id="people" class="com.wwy.JavaBean.NoteConfig.People">
<!--这里通过property和constructor-arg同时设置一个属性name,最终name的值是property1而不是constructor1-->
<property name="name" value="property1"></property>
<constructor-arg name="name" value="constructor1"></constructor-arg>
</bean>
<bean id="company" class="com.wwy.JavaBean.NoteConfig.Company"></bean>
public class Company {
@Autowired
private People people;
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
}
三、Java显式装配Bean
—接口及实现子类
public interface JavaBeanDesc {
public String way();
}
public class JavaBeanDescImpl implements JavaBeanDesc {
@Override
public String way() {
return "JavaBeanDescImpl way.";
}
}
public class JavaConstructorDesc {
private JavaBeanDesc javaBeanDesc;
public JavaConstructorDesc(JavaBeanDesc javaBeanDesc){
this.javaBeanDesc = javaBeanDesc;
}
public String way(){
return "JavaConstructorDesc "+javaBeanDesc.way();
}
}
—JavaConfig类
@Configuration和@Bean将对应的类注入成Bean对象。
@Configuration //配置spring容器(应用上下文),将该类注入成Bean对象
public class JavaConfig {
@Bean
public JavaBeanDesc getJavaBeanDesc(){
return new JavaBeanDescImpl();
}
@Bean
public JavaConstructorDesc getJavaConstructorDesc(JavaBeanDesc desc){
return new JavaConstructorDesc(desc);
}
}
@Component
public class JavaBeanDescV2 {
@Autowired
JavaBeanDesc javaBeanDesc; //前面已经注入成Bean对象,所以直接装配使用
public String way(){
return "JavaBeanDescV2 "+javaBeanDesc.way();
}
}
—测试方法
@Service
public class JavaBeanService {
@Autowired
JavaBeanDesc javaBeanDesc;
@Autowired
JavaConstructorDesc javaConstructorDesc;
@Autowired
JavaBeanDescV2 javaBeanDescV2;
public void test(){
System.out.println(javaBeanDesc.way());
System.out.println(javaConstructorDesc.way());
System.out.println(javaBeanDescV2.way());
}
}
四、混合装配Bean
注意:下面的是参考其他博客的,具体的没尝试过。
(一)多个JavaConfig类进行配置:
在每个配置类上使用@Configuration注解;
在其中一个配置类上使用@Import(AnotherJavaConfigClass.class)即可实现导入;
【也可以在一个统一的JavaConfig类上使用@Import注解导入其他的所有JAVA配置类:@Import(AnotherJavaConfigClass.class, SomeElseJavaConfigClass.class)】
(二)在JavaConfig类中导入在XML中配置的Bean:
1.在Java配置类上增加一个@ImportResource注解:@ImportResource(“classpath:cd-config.xml”)
(三)在XML中导入另一个XML配置文件:
1.在目标XML文件中使用元素:<import resource=“cd-config.xml”
(四)没有一个直接的方法能将JavaConfig类导入到xml文件,间接的,通过声明一个配置累的Bean来导入: