博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring - Java-based configuration: Using @Configuration
阅读量:6452 次
发布时间:2019-06-23

本文共 3871 字,大约阅读时间需要 12 分钟。

@Configuration

这是一个类级注解。如下所示,被它注解的类可能包含多个被@Bean注解的方法。Spring容器会调用这些方法,获得你初始化后的对象实例,并把他们注册为容器内的beans。

package spring.example@Configurationpublic class MyAppConfig {    @bean    public SomeBean someBean() {        // 实例化并返回,也可进行初始化        return new SomeBeanImpl();    }}

同等作用的XML配置会像下面这样:

clipboard.png

@Configuration类们实际上就是Spring管理的用于创建并注册bean实例的工厂。

Spring容器的启动

在Java-based的配置方式下,spring容器可以被AnnotationConfigApplicationContext启动,或者,针对Web应用AnnotationConfigWebApplicationContext也行。

new AnnotationConfigApplicationContext(MyAppConfig.class);

我们也可以指定包含了@Configuration类的有效包名:

new AnnotationConfigApplicationContext("spring.example");

基于上述两个重载方法,我们可以在单个package下放进多个JavaConfig类。

使用多个JavaConfig类

new AnnotationConfigApplicationContext( AppConfig.class, DataSourceConfig.class );new AnnotationConfigApplicationContext("example.spring.app","example.spring.datasource");

配置类中的依赖注入

既然配置类会被Spring容器注册成beans,那意味着,我们可以像使用普通bean那样使用这个配置bean。在以下例子我们要把这个一个配置bean注入给另一个配置bean:

@Configurationpublic class AppConfig {    // 方式一:注入DataSourceConfig    @Autowired    private DataSourceConfig dataSourceConfig;    @Bean    Client clientBean() {        return new Client(dataSourceConfig.dataSourceBean());    }    public static void main(String[] args) {        AnnotationConfigApplicationContext context =          new AnnotationConfigApplicationContext(AppConfig.class, DataSourceConfig.class);        context.getBean(Client.class).showData();    }            // 方式二:为何要那么麻烦呢?直接注入DataSourceBean不就好了?    @Autowired    private DataSourceBean dataSourceBean;    @Bean    Client clientBean() {        return new Client(dataSourceBean);    }}@Configurationclass DataSourceConfig {    @Bean    DataSourceBean dataSourceBean() {        return new DataSourceBean();    }}class Client {    private DataSourceBean dataSourceBean;    Client(DataSourceBean dataSourceBean){        this.dataSourceBean = dataSourceBean;    }    public void showData() {        System.out.println(dataSourceBean.getData());    }}class DataSourceBean {    public String getData() {        return "some data";    }}

在JavaConfig中使用构造器注入

从Spring 4.3开始,配置类开始支持使用构造器注入,可以从以下例子感受下何种场景下可以使用这个特性,see also:

@Configuration@ComponentScan({"com.logicbig.example.service", "com.logicbig.example.client"})public class ConfigurationImplicitConstructor {    private final OrderService orderService;    public ConfigurationImplicitConstructor (OrderService orderService) {        this.orderService = orderService;    }    @Bean(name = "services")    public List
services(){ return Arrays.asList(orderService); } public static void main (String... strings) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( ConfigurationImplicitConstructor.class); Object services = context.getBean("services"); System.out.println(services); }}

@Configuration类都会被CGLIB子类化

所有的@Configuration类都会在应用启动阶段被CGLIB进行子类化。在生成的子类当中,子方法会首先检查容器内已缓存的beans,如果已缓存的beans中没有当前实例,子方法才会真正去调用父方法,即是真正创建一个新的对象实例
在@Configuration类的@Bean方法中调用的[方法或字段],就是通过CGLIB代理,去对协作对象创建bean元数据引用。

这同时也是为何多次调用同一方法时,只会返回同一个实例的原因(因为默认的scoped为singleton)。

@Configuration注解是必须的,否则这个CGLIB代理不会被Spring执行。
运行以下代码,你可以看到输出结果是一致的。另外也可以把@Configuration去掉后,再运行看看结果。

@Configurationpublic class SpringConfig {    @Bean    public String something(){        return new String(System.nanoTime());    }    public static void main(String... strings) {        AnnotationConfigApplicationContext context =              new AnnotationConfigApplicationContext(SpringConfig.class);        System.out.println("Spring container started and is ready");        SpringConfig bean = context.getBean(SpringConfig.class);        System.out.println(bean.something());        System.out.println(bean.something());    }}

请注意在上例中,SpringConfig是作为一个bean实例被我们获取到的。这也是@Configuration类会被作为bean注册的一个有力证明。

转载地址:http://eogwo.baihongyu.com/

你可能感兴趣的文章
grub ubuntu关闭gnu_VMWare启动Ubuntu GNU grub 怎么进入界面系统
查看>>
java创建界面四句代码_Java并发的四句箴言
查看>>
java中面向字符的数据流_Java知多少(68)面向字符的输出流
查看>>
java的浅克隆_java浅克隆与深克隆
查看>>
java递归深度限制_为什么我可以达到不确定的最大递归深度?
查看>>
java更新停止程序_不停止JVM动态更新Java类
查看>>
java怎么创建属性类_怎么建立java类属性
查看>>
怎么让access数据库连接到Java_如何将Java连接到MS Access数据库
查看>>
java企业级应用开发设计总结_JavaEE(企业级应用开发)学习路线及知识总结
查看>>
java8u162环境_java - 日志文件未使用log4j 1.2.17和java8u162进行翻转 - 堆栈内存溢出...
查看>>
java如何导入扫描类_java – 导入扫描程序类的问题
查看>>
java迷你图书管理_JAVA高级特性——迷你图书管理系统(DOM4J操作存储集合中的对象)...
查看>>
java实现pdf旋转_基于Java实现PDF文本旋转倾斜
查看>>
java二维数组内存模型_C++二级指针第二种内存模型(二维数组)
查看>>
java static import 与 import_Java中的import和static import语句之间有什么区别?
查看>>
python time库3.8_python3中datetime库,time库以及pandas中的时间函数区别与详解
查看>>
java 代替Python_Java总是“沉沉浮浮”,替代者会是Python?
查看>>
贪吃蛇java程序简化版_JAVA简版贪吃蛇
查看>>
poi java web_WebPOI JavaWeb 项目 导出excel表格(.xls) Develop 238万源代码下载- www.pudn.com...
查看>>
java 顶点着色_金属顶点着色器绘制纹理点
查看>>