文章目录
Spring Bean 的装配
Spring 提供了多种类型的应用上下文:
AnnotationConfigApplicationContext
:基于 Java 的配置类中加载ClassPathXmlApplicationContext
:从类路径下基于 XML 的配置文件中加载FileSystemXmlApplicationContext
:从文件系统下基于 XML 的配置文件中加载
通过 XML 配置文件装配 bean
定义一个 XmlBean 类,其中依赖 OtherBean
public class XmlBean {
private String name;
private OtherBean otherBean;
public XmlBean(String name, OtherBean otherBean) {
this.name = name;
this.otherBean = otherBean;
System.out.println("通过XML配置文件装配Bean的构造方法");
}
@Override
public String toString() {
return "XmlBean{" +
"name='" + name + '\'' +
", otherBean=" + otherBean +
'}';
}
}
public class OtherBean {
}
在 bean.xml 配置文件中通过 <bean>
元素声明一个 bean 。<constructor-arg>
构造器注入初始化 bean ,其中 value
属性表明给定的值以字面量的形式注入到构造器中, ref
属性表明正在装配的是一个引用。
<?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="otherBean" class="com.chen.bean.assembly.xml.OtherBean" />
<bean id="xmlBean" class="com.chen.bean.assembly.xml.XmlBean">
<constructor-arg index="0" type="java.lang.String" value="xml"/>
<constructor-arg index="1" type="com.chen.bean.assembly.xml.OtherBean" ref="otherBean" />
</bean>
</beans>
使用 Junit 测试 Bean 是否装配成功
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.junit.Assert.*;
public class XmlBeanTest {
private ApplicationContext context;
@Before
public void before() {
context = new ClassPathXmlApplicationContext("bean.xml");
}
@Test
public void test() {
XmlBean bean = context.getBean(XmlBean.class);
assertNotNull(bean);
System.out.println(bean);
}
}
通过 Java 代码装配 bean
定义一个简单的 JavaBean 对象
public class JavaBean {
public JavaBean() {
System.out.println("通过Java代码装配Bean的构造方法");
}
}
通过 @Configuration
表明该类为 Bean 的配置类
通过 @Bean
配置和初始化 JavaBean 交给 Spring IoC 容器管理
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JavaBeanConfig {
@Bean
public JavaBean javaBean(){
return new JavaBean();
}
}
使用 Junit 测试 Bean 是否装配成功
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertNotNull;
public class JavaBeanConfigTest {
private ApplicationContext context;
@Before
public void before() {
context = new AnnotationConfigApplicationContext(JavaBeanConfig.class);
}
@Test
public void test() {
assertNotNull(context.getBean(JavaBean.class));
}
}
自动化扫描装配 bean
Spring 从两个角度来实现自动化装配:
- 组件扫描(component scanning):Spring 会自动发现应用上下文中所创建的 bean
- 自动装配(autowiring):Spring 自动满足 bean 之间的依赖
1. 基于 Java 代码注解
使用 @Component
定义 AutowireBean 是 Spring 的一个组件类,其中可以通过 value
属性来设置 bean 的别名
import org.springframework.stereotype.Component;
@Component(value = "bean")
public class AutowireBean {
public AutowireBean() {
System.out.println("自动装配Bean的构造方法");
}
}
通过 @CompoentScan
启用 Spring 的组件扫描,默认扫描与配置类相同的包以及子包,其中可以通过 basePackages
属性指定扫描的包名,还可以通过 basePackageClasses
属性指定扫描的类名
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackageClasses = AutowireBeanConfig.class)
public class AutowireBeanConfig {
}
使用 Junit 测试 Bean 是否自动装配成功
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertNotNull;
public class AutowireAutowireBeanConfigTest {
private ApplicationContext context;
@Before
public void before() {
context = new AnnotationConfigApplicationContext(AutowireBeanConfig.class);
}
@Test
public void test() {
assertNotNull(context.getBean(AutowireBean.class));
assertNotNull(context.getBean("bean"));
}
}
2. 基于 XML 配置文件
使用 Spring context 命名空间的 <context:component-scan>
元素开启自动扫描装配
<?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/beans/spring-context.xsd">
<context:component-scan base-package="com.chen.bean.assembly.autowire"/>
</beans>
混合配置
1. 在 JavaConfig 中引入 XML 配置
@Import(BeanConfig.class)
:引入基于 Java 代码配置的 BeanConfig
@ImportResource("classpath:bean.xml")
:引入基于 XML 配置的 bean.xml
@Configuration
@Import(BeanConfig.class)
@ImportResource("classpath:bean.xml")
public class JavaBeanConfig {
}
2. 在 XML 配置中引入 JavaConfig
<bean>
:引入基于 Java 代码配置的 JavaBeanConfig
<import>
:导入基于 XML 配置 的 bean.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"
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/beans/spring-context.xsd">
<bean class="JavaBeanConfig" />
<import resource="bean.xml" />
</beans>