一 JavaConfig
1 介绍
JavaConfig是Spring项目的一个子项目,在Spring 3.0开始从一个独立的项目并入到Spring中,并在Spring 4后成为核心功能。它提供了配置Spring IoC容器的纯Java方法,有助于避免使用传统的XML配置方式。使用JavaConfig的优点主要体现在以下几个方面:
面向对象的配置:由于配置被定义为JavaConfig中的类,用户可以充分利用Java中的面向对象功能,如封装、继承和多态等。
类型安全的配置:由于Java 5.0对泛型的支持,现在可以按类型而不是按名称检索bean,不需要任何强制转换或基于字符串的查找。
灵活性和可维护性:通过Java代码来配置Spring容器,使得配置更加灵活,易于维护和管理。同时,JavaConfig也支持将多个配置类合并,类似于XML配置中的include标签。
在JavaConfig中,通常会使用@Configuration注解来标记一个配置类,然后使用@Bean注解来定义和初始化bean。此外,还可以使用@ComponentScan注解来自动扫描和注册组件。
需要注意的是,虽然JavaConfig提供了纯Java的配置方式,但很多人认为将JavaConfig与XML混合匹配是理想的。这取决于具体项目的需求和团队的偏好。JavaConfig为开发人员提供了一种更加灵活、面向对象和类型安全的配置Spring容器的方式,是现代Spring开发中不可或缺的一部分。
2 XML 方式配置 IoC
① 导入依赖
java
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
② 定义Bean
java
// 第一个
public class OtherBean {
public OtherBean() {
System.out.println("OtherBean 被创建");
}
}
// 第二个
public class SomeBean {
private OtherBean otherBean;
// set注入
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
public SomeBean() {
System.out.println("SomeBean 被创建");
}
public void init() {
System.out.println("SomeBean 被初始化");
}
public void destroy() {
System.out.println("SomeBean 被销毁");
}
@Override
public String toString() {
return "SomeBean{" +
"otherBean=" + otherBean +
'}';
}
}
③ 配置文件 -- spring-core.xml
java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--创建bean-->
<bean id="someBean" class="cn.tj.bean.SomeBean">
<property name="otherBean" ref="otherBean"></property>
</bean>
<bean id="otherBean" class="cn.tj.bean.OtherBean" ></bean>
</beans>
<!--<context:component-scan base-package="cn.tj"></context:component-scan>-->
④ 测试类
java
/*xml配置bean对象*/
@Test
public void ioc_test01() {
//获取somebean 加载配置文件
ApplicationContext context=new ClassPathXmlApplicationContext("spring-core.xml");
SomeBean someBean = (SomeBean) context.getBean("someBean");
System.out.println(someBean);
}
3 JavaConfig 方式配置 IoC
JavaConfig 方式中使用注解彻底的替代 XML 文件,即通过注解告诉 Spring 容器,bean 没有定义在 XML 文件中,而是定义在一个 Java 配置类中。
@Configuration
:在类上贴该注解表示该类是 Spring 的配置类,具有 applicationContext.xml 文件的作用。@Bean
:在 Spring 的配置类的方法上贴该注解后,该方法返回的对象会交给 Spring 容器管理,替代 applicationContext.xml 中的 bean 标签。@ComponentScan
:在 Spring 配置类上贴该注解表示开启组件扫描器,默认扫描当前配置类所在的包,也可以自己指定,替代 XML 配置中的<context:component-scan />
标签。AnnotationConfigApplicationContext
:该类是 ApplicationContext 接口的实现类,该对象是基于 JavaConfig 的方式来运作的 Spring 容器。(加载配置文件,也就是配置类)
① 配置类 -- SpringConfig(主启动类需放在其他包和类的上一级目录才能进行扫描)
java
//声明当前类是一个配置类
@Configuration
//@configuration componentScanconfigutation componentScan
//注解扫描:扫描当前包及其子包注解
@ComponentScan
public class SpringConfig {
//相当于Bean标签
@Bean
public SomeBean someBean(OtherBean otherBean){
SomeBean someBean=new SomeBean();
someBean.setOtherBean(otherBean);//bean作为方法的形参传入 完成注入
return someBean;
}
@Bean
public OtherBean otherBean(){
return new OtherBean();
}
// @Bean(initMethod = "init",destroyMethod = "destroy")
// @Scope("prototype")
// @Bean
// public SomeBean someBean( ){
// SomeBean someBean=new SomeBean();
// someBean.setOtherBean(otherBean());//调用bean的方法注入也可以
// return someBean;
// }
}
② 测试类
java
/*javaconfig配置bean对象*/
@Test
public void ioc_test02() {
// 加载配置类 由于2个Bean都在配置类中 故直接生成2个Bean
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
SomeBean someBean = (SomeBean) context.getBean("someBean");
System.out.println(someBean);
context.close();
}
4 使用 IoC DI 注解简化配置
通过注解简化 JavaConfig
① Bean
java
// 第一个
@Component
public class OtherBean {
public OtherBean() {
System.out.println("OtherBean 被创建");
}
}
// 第二个
@Component
public class SomeBean {
@Autowired
private OtherBean otherBean;
// public void setOtherBean(OtherBean otherBean) {
// this.otherBean = otherBean;
// }
public SomeBean() {
System.out.println("SomeBean 被创建");
}
public void init() {
System.out.println("SomeBean 被初始化");
}
public void destroy() {
System.out.println("SomeBean 被销毁");
}
@Override
public String toString() {
return "SomeBean{" +
"otherBean=" + otherBean +
'}';
}
}
② 配置类
java
@Configuration
//@configuration componentScanconfigutation componentScan
//注解扫描:扫描当前包及其子包注解
@ComponentScan
public class SpringConfig {
// 略
}
5 Spring Test 方式加载配置类
① 导入依赖
java
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.3</version>
<scope>test</scope>
</dependency>
② JUnit4 的方式
java
@RunWith(SpringJUnit4ClassRunner.class)
//读取xml配置文件 需配置<context:component-scan>扫描
//@ContextConfiguration("classpath:spring-core.xml")
//读取配置类 需配置注解
@ContextConfiguration(classes = {SpringConfig.class})
public class Junit4BeanTest {
@Autowired
private SomeBean someBean;
@Test
public void test1() {
System.out.println(someBean);
}
}
③ JUnit5 的方式
java
// 读配置文件
//@SpringJUnitConfig(locations = {"classpath:spring-core.xml"})
// 读配置类
@SpringJUnitConfig(classes = {SpringConfig.class})
public class Junit5BeanTest {
@Autowired
private SomeBean someBean;
@Test
public void test1() {
System.out.println(someBean);
}
}
6 配置类的导入
项目中一般都会有多个 Spring 的配置文件,分别配置不同的组件,最后关联到主配置文件中,该功能也是同样可以在配置类的方式中使用的。
① xml方式
java
<!-- mvc.xml 中导入 applicationContext.xml -->
<import resource="classpath:applicationContext.xml"/>
② 配置类方式
java
// 主配置类
@Configuration
@Import(JavaConfigA.class) // 在主配置类中关联次配置类
public class JavaConfig { ... }
// 次配置类
@Configuration
public class JavaConfigA { ... }
// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class Test { ... }
③ 配置类导入 XML 配置
java
// 用@ImportResource指定导入 XML 配置文件的路径
// 主配置类
@Configuration
@ImportResource("classpath:XML文件路径") // 在主配置类中关联 XML 配置
public class JavaConfig { ... }
// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class IoCTest { ... }