Spring框架学习笔记-基于Java类的配置
1.使用Java类提供Bean定义信息
普通的POJO只要标注@Configuration注解,就可以为Spring容器提供Bean定义的信息了,每个标注了@Bean的类方法都相当于提供一个Bean的定义信息。
package com.baobaotao.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//说明这个类可以用于为Spring提供Bean的定义信息
public class AppConf{
@Bean
//以下两个方法定义了两个Bean,并提供了Bean的实例化逻辑,Bean的类型由方法返回值类型决定,名称默认和方法名相同,当然也可以通过入参显式指定Bean名称,如@Bean(name="userDao")。直接再@Bean所标注的方法中提供Bean的实例化逻辑
public UserDao userDao(){
return new UserDao();
}
@Bean
public LohDao logDao(){
return new LogDao();
}
@Bean
public LogonService logonService(){
LogonService logonService=new LogonService();
//将前面定义的Bean注入到logonService Bean中
logonService.setLogDao(logDao());
logonService.setUserDao(userDao());
return logonService;
}
}
userDao()方法和logDao()方法定义了一个UserDao和一个LogDao的Bean,它们的Bean名称分别为userDao和logDao。并且后面又定义了一个logonService Bean,并且注入了前面两个Bean。因此以上的配置和以下的XML配置是等效的:
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
<bean id="logDao" class="com.baobaotao.anno.LogDao"/>
<bean id="logonService" class="com.baobaotao.conf.LogonService" p:userDao-ref="userDao" p:logDao-ref="logDao"/>
基于Java类的配置方式和基于XML或是基于注解的配置方式相比,前者通过代码的方式更加灵活地实现了Bean的实例化以及Bean的装配,但是后面两者都是通过配置声明的方式,再灵活上稍显不足,但是配置上却更简单一些。
如果Bean在多个@Configuration配置类中定义,如何引用不同配置类中定义的Bean呢?例如,UserDao和LogDao这两个Bean在DaoConfig中定义,而LogonService Bean在Service中定义,
LogonService Bean需要引用DaoConfig中定义的两个Bean:
package com.baobaotao.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuratiom;
@Configuration
public class DaoConfig{
@Bean
public UserDao userDao(){
return new UserDao();
}
@Bean
public LogDao logDao(){
return new LogDao();
}
}
由于@Configuration注解类本身已经标注了@Component注解,所以任何标注了@Configuration的类,本身也相当于标注了@Component,即它们可以像普通的Bean一样被注入到其他类当中。DaoConfig标注了@Configuration注解后就成为了一个Bean,它可以被自动注入到ServiceConfig中:
@Configuration
public class ServiceConfig{
@Autowired
private DaoConfig daoConfig;
@Bean
public LogonService logonService(){
LogonService logonService=new LogonService();
logonService.setLogDao(daoConfig.logDao());
logonService.setUserDao(daoConfig.userDao());
return logonService;
}
}
调用daoConfig的logDao()和userDao()方法,就相当于将DaoConfig配置类中定义的Bean注入进来,Spring会对配置类所有标注@Bean的方法进行AOP增强,将对Bean声明周期管理的逻辑植入进来。所以当我们执行daoConfig.logDao()方法时,不是简单地执行DaoConfig类中定义的方法逻辑,而是从Spring容器中返回相应的Bean的单例。换句话说,多次调用daoConfig.logD
ao()方法时,返回的都是Spring容器中相同的Bean。在@Bean处,还可以标注@Scope注解以控制Bean的作用范围。如果在@Bean处标注了@Scope(“prototype”),则每次调用的时候则是一个新的Bean。
public class DaoConfig{
@Scope("prototype")
@Bean
public LogDao logDao(){
return new LogDao();
}
}
最后,需要特别注意的是,由于Spring容器会自动对@Configuration的类进行改造,以植入Spring容器对Bean的管理逻辑,所以使用基于Java类的配置必须保证Spring aop类包和CGLIB类包加载到类路径下。
2.使用基于Java类的配置信息启动Spring容器
2.1直接通过@Configuration类启动Spring容器
Spring提供了一个AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的Java类启动Spring容器:
public class JavaConfigTest{
public static void main(String[] args){
ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConf.class);
LogonService logonService=ctx.getBean(LogonService.class);
logonService.printHello();
}
}
通过AnnotationConfigApplicationContext类的构造函数直接传入标注@Configuration的Java类,直接用该类中提供的Bean定义信息启动Spring容器。
2.2 XML配置文件引用@Configuration的配置
标注了@Configuration的配置类本身相当于一个标注了@Component的类,一样也是一个Bean,它可以被Spring的< context:component-scan >扫描到。因此,如果希望将配置类组装到XML配置文件中,通过XML配置文件启动Spring容器,仅需要在XML文件中通过< context:component-scan >扫描到相应的配置类就可以了。
<context:component-scan base-package="com.baobaotao.conf" resource-pattern="AppConf.class"/>
2.3Configuration配置类引用XML配置信息
假设在beans3.xml中定义了两个Bean:
<bean id="userDao" class="com.baobaotao.conf.UserDao"/>
<bean id="logDao" class="com.baobaotao.conf.LogDao"/>
在@Configuration配置类中可以通过@ImportResource引入XML配置文件,在配置类中即可直接通过@Autowired引用XML配置文件中定义的Bean:
@Configuration
@ImportResource("classpath:com/baobaotao/conf/beans3.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;
}
}
它完成了两项功能:其一、定义了一个LogonService的Bean;其二,通过方法入参自动注入UserDao和LogDao的Bean,这两个Bean是在XML中定义的。
推荐阅读
-
5.3类集(java学习笔记)集合的输出
-
oracle学习笔记(八)——结果集元数据ResultSetMetaData以及ResultSet转为对应的实体类框架
-
Spring学习笔记第二天,Spring基于xml或注解的IOC以及IOC的案例
-
java 学习笔记 day07 类的继承、多态、super关键字
-
Java学习笔记-全栈-web开发-22-后端程序员用的前端框架——layUI
-
Mule ESB 学习笔记(15)CXF SOAP基于JKS的验证的配置
-
spring的基于java的项目配置示例2
-
Spring-基于Java类的配置
-
Spring入门学习笔记(2)——基于Java的配置
-
Spring 框架的概述以及Spring中基于XML的IOC配置