Spring-基于Java类的配置
概述
JavaConfig是Spring的一个子项目,它旨在通过Java类的方式提供Bean的定义信息,在Spring4.0的版本,JavaConfig正式成为Spring4.0的核心功能。
使用Java类提供Bean定义信息
普通的POJO只要标注了@Configuration注解,就可以为Spring容器提供Bean定义的信息,每个标注了@Bean的类方法都相当于提供一个Bean的定义信息。
实例
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster
POJO
package com.xgj.ioc.javaConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 将一个POJO标注为定义Bean的配置类
@Configuration
public class Teacher {
/**
*
*
* @Title: studentOne
*
* @Description: 定义了一个Bean,并提供了Bean的实例化逻辑
*
* @return
*
* @return: StudentOne
*/
@Bean
public StudentOne studentOne() {
return new StudentOne();
}
/**
*
*
* @Title: studentTwo
*
* @Description: 定义了一个Bean,并提供了Bean的实例化逻辑
*
* @return
*
* @return: StudentTwo
*/
@Bean
public StudentTwo studentTwo() {
return new StudentTwo();
}
public void arrangeStudent() {
studentOne().doCleanWork();
studentTwo().doHomeWork();
}
}
package com.xgj.ioc.javaConfig;
public class StudentOne {
public void doCleanWork() {
System.out.println("StudentOne will do CleanWork");
}
}
package com.xgj.ioc.javaConfig;
public class StudentTwo {
public void doHomeWork() {
System.out.println("StudentTwo will do HomeWork");
}
}
测试类
package com.xgj.ioc.javaConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(
Teacher.class);
ctx.getBean("teacher", Teacher.class).arrangeStudent();
}
}
运行结果
分析
Teacher类的定义出标注了@Configuration注解,说明这个类可以用于为Spring提供Bean的定义信息。
该类的方法可以标注@Bean注解,Bean的类型由方法返回值的类型决定,名称默认和方法名同名,当然也可以通过入参显示指定Bean名称,比如@Bean(name=”coolStudent”).
@Bean所标注的方法体提供了Bean的实例化逻辑。
studentOne()和studentTwo()方法分别定义了一个StudentOne 和 StudentTwo类型的Bean, 他们的Bean名称分别为 studentOne 和 studentTwo。
在arrangeStudent()方法中 注入了上面实例化的两个Bean。
以上配置和下面的xml是等效的
<bean id="studentOne" class="com.xgj.ioc.javaConfig.StudentOne"/>
<bean id="studentTwo" class="com.xgj.ioc.javaConfig.StudentTwo"/>
<bean id="teacher" class="com.xgj.ioc.javaConfig.Teacher"
p:sutdentOne-ref="studentOne" p:studentTwo-ref="studentTwo"/>
基于Java类的配置方式和基于XML或者基于注解的配置方式相比,前者通过代码编程的方式可以更加灵活的实现Bean的实例化及Bean之间的装配,后两者都是通过配置声明的方式,在灵活性上要稍逊一些,但在配置上要更简单一些。
使用基于Java类的配置信息启动Spring容器
1.直接通过@Configuration启动Spring容器
Spring提供了AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的Java类启动Spring容器。
通过AnnotationConfigApplicationContext的构造函数加载配置类
比如我们上面的那个例子的测试类
package com.xgj.ioc.javaConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
// (1)通过构造函数加载配置类
ApplicationContext ctx = new AnnotationConfigApplicationContext(
Teacher.class);
ctx.getBean("teacher", Teacher.class).arrangeStudent();
}
}
在(1)处,通过AnnotationConfigApplicationContext类的构造函数直接传入标注了@Configuration的JAVA类,这届用该类中提供的Bean定义信息启动Spring容器。
通过编码的方式加载多个@Configuration配置类,然后通过刷新容器应用这些配置类
package com.xgj.ioc.javaConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
// 通过构造函数加载配置类
// ApplicationContext ctx = new AnnotationConfigApplicationContext(
// Teacher.class);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// 注册@Configuration的配置类,可注册多个
ctx.register(Teacher.class);
// 刷新容器以应用这些注册的配置类
ctx.refresh();
Teacher teacher = ctx.getBean("teacher", Teacher.class);
teacher.arrangeStudent();
}
}
通过@Import将多个配置类组装到一个配置类中,然后仅需注册这个组装好的配置类 ,启动容器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(DaoConfig.class)
public class ServiceConfig {
@Autowired
private DaoConfig daoConfig;
@Bean
public LogonService logonService(){
LogonService logonService = new LogonService();
System.out.println(daoConfig.logDao() == daoConfig.logDao());
logonService.setLogDao(daoConfig.logDao());
logonService.setUserDao(daoConfig.userDao());
return logonService;
}
}
AnnotationConfigApplicationContext的主要方法
2.通过XML配置文件引用@Configuration配置
标注了@Configuration的配置类和标注了@Component的类一样也是一个Bean, 同样的 它也可以被Spring的<context:component-scan>
扫描到。 因此如果希望将配置类组装到XML的配置文件中,通过XML的配置文件启动Spring,这仅需要在XML子中通过<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/context/spring-context.xsd">
<!-- (1)声明Context命名空间以及Schema文件 (2)扫描类包以及应用注解定义的bean resource-pattern 看需求,可配置可不配置 -->
<context:component-scan base-package="com.xgj.ioc.javaConfig"
resource-pattern="Teacher.class" />
</beans>
package com.xgj.ioc.javaConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:com/xgj/ioc/javaConfig/beans.xml");
Teacher teacher = ctx.getBean("teacher", Teacher.class);
teacher.arrangeStudent();
}
}
同样也可以正确的加载并实例化Bean
2017-07-31 22:03:02,093 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@d167d36: startup date [Mon Jul 31 22:03:02 BOT 2017]; root of context hierarchy
2017-07-31 22:03:02,176 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/ioc/javaConfig/beans.xml]
StudentOne will do CleanWork
StudentTwo will do HomeWork
3.通过@Configuration配置类引用XML配置信息
假设bean中有两个Bean ,如下
<bean id="userDao" class="com.xgj.ioc.javaConfig.UserDao"/>
<bean id="logDao" class="com.xgj.ioc.javaConfig.LogDao"/>
在@Configuration配置类中可以直接通过@ImportResource引入XML的配置那文件,这样就就可以直接通过@Autowired引用xml配置文件中定义的Bean。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource("classpath:com/xgj/ioc/javaConfig/beans.xml")
public class LogonAppConfig {
@Bean
@Autowired
public LogonService logonService(UserDao userDao,LogDao logDao){
LogonService logonService = new LogonService();
logonService.setUserDao(userDao);
logonService.setLogDao(logDao);
return logonService;
}
}
通过@ImportResource引入XML配置文件
通过@Bean定义一个LogonService 的bean
通过@Autowired自动注入userDao和logDao ,这两个Bean是在XML配置文件中定义的。
需要说明的是,@ImportResource引入XML配置文件,不是@Autowired处可成功注入到对应Bean的前提条件。 只要不同形式的Bean定义信息能够加载到Spring容器中,Spring就可以智能的完成Bean之间的装配。
推荐阅读
-
基于JavaScript实现类名的添加与移除
-
java 抽象类和接口的区别详细解析
-
[Java] 父类和子类拥有同名的成员变量(fields)的情况
-
我竟然不再抗拒 Java 的类加载机制了
-
Springboot 2.0.x 集成基于Centos7的Redis集群安装及配置
-
Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate
-
基于windows server 2016和sqlserver 2016 AlwaysOn的群集配置
-
Java基于WebMagic爬取某豆瓣电影评论的实现
-
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
-
一个基于PDO的数据库操作类