文章目录
- 基于 配置类 方式管理 Bean
- 一、 配置类和扫描注解
- 二、@Bean定义组件
- 三、高级特性:@Bean注解细节
- 四、高级特性:@Import扩展
- 五、基于注解+配置类方式整合三层架构组件
- 总结
基于 配置类 方式管理 Bean
- Spring 完全注解配置(Fully Annotation-based Configuration)是指通过 Java配置类 代码来配置 Spring 应用程序,使用注解来替代原本在 XML 配置文件中的配置。
- 相对于 XML 配置,完全注解配置具有更强的类型安全性和更好的可读性。
从 xml 到 完全注解 配置!
一、 配置类和扫描注解
//使用注解读取外部配置,替代 <context:property-placeholder标签
@PropertySource("classpath:jdbc.properties")
//使用@ComponentScan注解,可以配置扫描包,替代<context:component-scan标签
@ComponentScan("com.doug.ioc01")
//标注当前类是配置类,替代application.xml
@Configuration
public class javaConfiguration {
/*
* 1. 添加@Configuration 标识为配置类
* 2. 包扫描注解配置:
* 2.1 @ComponentScan({"com.doug.ioc01","com.doug.ioc02"}) 多个包 中括号+逗号分割
* 2.2 引用外部配置文件
* 2.3 声明第三方依赖的bean组件
* */
}
测试:
@Test
public void testIoc_01(){
// AnnotationConfigApplicationContext 根据配置类创建 IOC 容器对象
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(javaConfiguration.class);
StuController bean = context.getBean(StuController.class);
bean.show();
}
也可以使用 no-arg 构造函数实例化 AnnotationConfigApplicationContext
,然后使用 register()
方法对其进行配置。
// AnnotationConfigApplicationContext-IOC容器对象
ApplicationContext iocContainerAnnotation =
new AnnotationConfigApplicationContext();
//外部设置配置类
iocContainerAnnotation.register(MyConfiguration.class);
//刷新后方可生效!!
iocContainerAnnotation.refresh();
- @Configuration指定一个类为配置类,可以添加配置注解,替代配置xml文件
- @ComponentScan(basePackages = {“包”,“包”}) 替代<context:component-scan标签实现注解扫描
- @PropertySource(“classpath:配置文件地址”) 替代 <context:property-placeholder标签
- 配合IoC/DI注解,可以进行完整注解开发!
二、@Bean定义组件
属性只在当前方法使用,直接写成形参
//标注当前类是配置类,替代application.xml
@Configuration
//引入jdbc.properties文件
@PropertySource({"classpath:application.properties","classpath:jdbc.properties"})
@ComponentScan(basePackages = {"com.doug.components"})
public class MyConfiguration {
//如果第三方类进行IoC管理,无法直接使用@Component相关注解
//解决方案: xml方式可以使用<bean标签
//解决方案: 配置类方式,可以使用方法返回值+@Bean注解
@Bean
public DataSource createDataSource(@Value("${jdbc.user}") String username,
@Value("${jdbc.password}")String password,
@Value("${jdbc.url}")String url,
@Value("${jdbc.driver}")String driverClassName){
//使用Java代码实例化
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
//返回结果即可
return dataSource;
}
}
三、高级特性:@Bean注解细节
/*
* @Bean会真正让配置类的方法创建的组件存储到IOC容器
*
* 1. beanName
* 默认:方法名
* 指定:name/value 属性起名字,覆盖方法名
*
* 2. 周期方法指定
* 原有注解方法:PostConstruct + PreDestroy
* bean属性指定:initMethod / destroyMethod
*
* 3.作用域
* @Scope 默认单例
*
* 4.如何引用其他ioc组件
* 直接调用对方的bean方法
* 直接形参变量引入,要就必须有对应组件,如有多个,形参名 = 组件id标识 即可
* */
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Bean(name = "dataSource",initMethod = "",destroyMethod = "")
public DataSource createDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "dougSource")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/**
* 方法一:
* 直接把方法引入
* @return
*/
@Bean
public JdbcTemplate jdbcTemplate(){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(createDataSource());
return jdbcTemplate;
}
/**
* 方法二:
* 使用形参的方式,IOC容器会自动装配,可以一个或多个
* @return
*/
@Bean
public JdbcTemplate jdbcTemplate2(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//使用形参的方法,就必须要有这个类型的参数已经被注入了,
// 就是上面的createDataSource方法被@Bean注解标识了(没有标注是会报错的)
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
/**
* 如果是多个形参的情况,根据传入参数的名字对应bean设置的name,选择
*/
@Bean
public JdbcTemplate jdbcTemplate3(DataSource dataSource,DataSource dougSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//使用形参的方法,就必须要有这个类型的参数已经被注入了,
// 就是上面的createDataSource方法被@Bean注解标识了(没有标注是会报错的)
// 如果是多个形参的情况,根据传入参数的名字对应bean设置的name,选择
jdbcTemplate.setDataSource(dougSource);
return jdbcTemplate;
}
四、高级特性:@Import扩展
@Import
注释允许从另一个配置类加载 @Bean
定义
也就是 :
当有A B两个配置类, A中引入@Import
B
在实例化配置类时 , 只要引入A就可以,B会跟着一起。
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
容器实例化只需要引入 ConfigB.class (但是AB都可以用);
在实例化上下文时不需要同时指定 ConfigA.class
和 ConfigB.class
,只需显式提供 ConfigB
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
此方法简化了容器实例化,因为只需要处理一个类,而不是要求在构造期间记住可能大量的 @Configuration
类。
五、基于注解+配置类方式整合三层架构组件
将原xml 配置第三方类 都使用 配置类来写,其余用都用注解,也就是完全注解开发,舍弃了在xml里面配置
配置类:
@PropertySource("classpath:jdbc.properties")
@ComponentScan("com.doug")
@Configuration
public class MyConfiguration {
@Bean
public DataSource dataSource(
@Value("${doug.url}") String url, @Value("${doug.driver}") String driver,
@Value("${doug.username}") String username, @Value("${doug.password}") String password
) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}
总结
注解+配置类 IoC方式总结
- 完全摒弃了XML配置文件
- 自定义类使用IoC和DI注解标记
- 第三方类使用配置类声明方法+@Bean方式处理
- 完全注解方式(配置类+注解)是现在主流配置方式