`
jinnianshilongnian
  • 浏览: 21434672 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405078
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997748
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631488
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257577
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593183
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248974
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847568
Group-logo
跟我学Nginx+Lua开...
浏览量:698167
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780468
社区版块
存档分类
最新评论

【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3

阅读更多

12.4  基于Java类定义Bean配置元数据

12.4.1  概述

基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件。

 

基于Java类定义Bean配置元数据中的@Configuration注解的类等价于XML配置文件,@Bean注解的方法等价于XML配置文件中的Bean定义。

 

基于Java类定义Bean配置元数据需要通过AnnotationConfigApplicationContext加载配置类及初始化容器,类似于XML配置文件需要使用ClassPathXmlApplicationContext加载配置文件及初始化容器。

 

基于Java类定义Bean配置元数据需要CGLIB的支持,因此要保证类路径中包括CGLIB的jar包。

 

 

12.4.2  Hello World

首先让我们看一下基于Java类如何定义Bean配置元数据,具体步骤如下:

1、  通过@Configuration注解需要作为配置的类,表示该类将定义Bean配置元数据;

2、  通过@Bean注解相应的方法,该方法名默认就是Bean名,该方法返回值就是Bean对象;

3、  通过AnnotationConfigApplicationContext或子类加载基于Java类的配置。

 

 

 

接下来让我们先来学习一下如何通过Java类定义Bean配置元数据吧:

 

1、定义配置元数据的Java类如下所示:

 

java代码:
package cn.javass.spring.chapter12.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration 
public class ApplicationContextConfig {
    @Bean
    public String message() {
        return "hello";
    }
}

 

2、定义测试类,测试一下Java配置类是否工作:

 

java代码:
package cn.javass.spring.chapter12.configuration;
//省略import
public class ConfigurationTest {
    @Test
    public void testHelloworld () {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
        Assert.assertEquals("hello", ctx.getBean("message"));
    }
}

    测试没有报错说明测试通过了,那AnnotationConfigApplicationContext是如何工作的呢,接下来让我们分析一下:

  • 使用@Configuration注解配置类,该配置类定义了Bean配置元数据;
  • 使用@Bean注解配置类中的方法,该方法名就是Bean的名字,该方法返回值就是Bean对象。
  • 使用new AnnotationConfigApplicationContext(ApplicationContextConfig.class)创建应用上下文,构造器参数为使用@Configuration注解的配置类,读取配置类进行实例化相应的Bean。

 

知道如何使用了,接下来就详细介绍每个部分吧。

 

 

12.4.3  @Configuration

通过@Configuration注解的类将被作为配置类使用,表示在该类中将定义Bean配置元数据,且使用@Configuration注解的类本身也是一个Bean,使用方式如下所示:

 

java代码:
import org.springframework.context.annotation.Configuration;
@Configuration("ctxConfig")
public class ApplicationContextConfig {
    //定义Bean配置元数据
}

       因为使用@Configuration注解的类本身也是一个Bean,因为@Configuration被@Component注解了,因此@Configuration注解可以指定value属性值,如“ctxConfig”就是该Bean的名字,如使用“ctx.getBean("ctxConfig")”将返回该Bean。

 

使用@Configuration注解的类不能是final的,且应该有一个默认无参构造器。

 

12.4.4  @Bean

通过@Bean注解配置类中的相应方法,则该方法名默认就是Bean名,该方法返回值就是Bean对象,并定义了Spring IoC容器如何实例化、自动装配、初始化Bean逻辑,具体使用方法如下:

 

java代码:
@Bean(name={},
      autowire=Autowire.NO,
      initMethod="",
      destroyMethod="")
  • name指定Bean的名字,可有多个,第一个作为Id,其他作为别名;
  • autowire自动装配,默认no表示不自动装配该Bean,另外还有Autowire.BY_NAME表示根据名字自动装配,Autowire.BY_TYPE表示根据类型自动装配;
  • initMethod和destroyMethod指定Bean的初始化和销毁方法。

示例如下所示(ApplicationContextConfig.java)

 

java代码:
@Bean
public String message() {
    return new String("hello");
}

 

如上使用方式等价于如下基于XML配置方式

 

java代码:
<bean id="message" class="java.lang.String">
    <constructor-arg index="0" value="hello"/>
</bean>

    使用@Bean注解的方法不能是private、final或static的。

 

 

12.4.5  提供更多的配置元数据

       详见【12.3.6  提供更多的配置元数据】中介绍的各种注解,这些注解同样适用于@Bean注解的方法。

 

 

12.4.6  依赖注入

  基于Java类配置方式的Bean依赖注入有如下两种方式:

  • 直接依赖注入,类似于基于XML配置方式中的显示依赖注入;
  • 使用注解实现Bean依赖注入:如@Autowired等等。

 

在本示例中我们将使用【第三章  DI】中的测试Bean。

 

1、 直接依赖注入:包括构造器注入和setter注入。

  • 构造器注入:通过在@Bean注解的实例化方法中使用有参构造器实例化相应的Bean即可,如下所示(ApplicationContextConfig.java):

 

java代码:
@Bean
public HelloApi helloImpl3() {
    //通过构造器注入,分别是引用注入(message())和常量注入(1)
    return new HelloImpl3(message(), 1); //测试Bean详见【3.1.2  构造器注入】
}

 

  • setter注入:通过在@Bean注解的实例化方法中使用无参构造器实例化后,通过相应的setter方法注入即可,如下所示(ApplicationContextConfig.java):

 

java代码:
@Bean
public HelloApi helloImpl4() {
    HelloImpl4 helloImpl4 = new HelloImpl4();//测试Bean详见【3.1.3  setter注入】
    //通过setter注入注入引用
    helloImpl4.setMessage(message());
    //通过setter注入注入常量
    helloImpl4.setIndex(1);
    return helloImpl4;
}
 

 

 

2、使用注解实现Bean依赖注入:详见【12.2  注解实Bean依赖注入】。

 

    具体测试方法如下(ConfigurationTest.java):

 

java代码:
@Test
public void testDependencyInject() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
    ctx.getBean("helloImpl3", HelloApi.class).sayHello();
    ctx.getBean("helloImpl4", HelloApi.class).sayHello();
}

 

12.4.7  方法注入

在基于XML配置方式中,Spring支持查找方法注入和替换方法注入,但在基于Java配置方式中只支持查找方法注入,一般用于在一个单例Bean中注入一个原型Bean的情况,具体详见【3.3.5  方法注入】,如下所示(ApplicationContextConfig.java):

 

java代码:
@Bean
@Scope("singleton")
public HelloApi helloApi2() {
    HelloImpl5 helloImpl5 = new HelloImpl5() {
        @Override
        public Printer createPrototypePrinter() {
            //方法注入,注入原型Bean
            return prototypePrinter();
        }
        @Override
        public Printer createSingletonPrinter() {
            //方法注入,注入单例Bean
            return singletonPrinter();
        }
    };
    //依赖注入,注入单例Bean
    helloImpl5.setPrinter(singletonPrinter());
    return helloImpl5;
}

 

 

java代码:
@Bean
@Scope(value="prototype")
public Printer prototypePrinter() {
    return new Printer();
 }
@Bean
@Scope(value="singleton")
public Printer singletonPrinter() {
    return new Printer();
}
 

 

具体测试方法如下(ConfigurationTest.java):

 

java代码:
@Test
public void testLookupMethodInject() {
    AnnotationConfigApplicationContext ctx =
        new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
    System.out.println("=======prototype sayHello======");
    HelloApi helloApi2 = ctx.getBean("helloApi2", HelloApi.class);
    helloApi2.sayHello();
    helloApi2 = ctx.getBean("helloApi2", HelloApi.class);
    helloApi2.sayHello();
}

    如上测试等价于【3.3.5  方法注入】中的查找方法注入。

 

 

12.4.8  @Import

  类似于基于XML配置中的<import/>,基于Java的配置方式提供了@Import来组合模块化的配置类,使用方式如下所示:

 

java代码:
package cn.javass.spring.chapter12.configuration;
//省略import
@Configuration("ctxConfig2")
@Import({ApplicationContextConfig.class})
public class ApplicationContextConfig2 {
    @Bean(name = {"message2"})
    public String message() {
        return "hello";
    }
}

 

具体测试方法如下(ConfigurationTest.java):

 

java代码:
@Test
public void  importTest() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig2.class);
    Assert.assertEquals("hello", ctx.getBean("message"));
}

   使用非常简单,在此就不多介绍了。

 

12.4.9  结合基于Java和基于XML方式的配置

基于Java方式的配置方式不是为了完全替代基于XML方式的配置,两者可以结合使用,因此可以有两种结合使用方式:

  • 在基于Java方式的配置类中引入基于XML方式的配置文件;
  • 在基于XML方式的配置文件中中引入基于Java方式的配置。

 

一、在基于Java方式的配置类中引入基于XML方式的配置文件:在@Configuration注解的配置类上通过@ImportResource注解引入基于XML方式的配置文件,示例如下所示:

1、定义基于XML方式的配置文件(chapter12/configuration/importResource.xml):

 

java代码:
<bean id="message3" class="java.lang.String">
    <constructor-arg index="0" value="test"></constructor-arg>
</bean>

 

2、修改基于Java方式的配置类ApplicationContextConfig,添加如下注解:

 

java代码:
@Configuration("ctxConfig") //1、使用@Configuration注解配置类
@ImportResource("classpath:chapter12/configuration/importResource.xml")
public class ApplicationContextConfig {
……
}

 

使用@ImportResource引入基于XML方式的配置文件,如果有多个请使用@ImportResource({"config1.xml", "config2.xml"})方式指定多个配置文件。

 

 

二、在基于XML方式的配置文件中中引入基于Java方式的配置:直接在XML配置文件中声明使用@Configuration注解的配置类即可,示例如下所示:

 

1、定义基于Java方式的使用@Configuration注解的配置类在此我们使用ApplicationContextConfig.java。

 

2、定义基于XML方式的配置文件(chapter12/configuration/xml-config.xml):

 

java代码:
<context:annotation-config/>
<bean id="ctxConfig" class="cn.javass.spring.chapter12.configuration.ApplicationContextConfig"/>
  • <context:annotation-config/>:用于开启对注解驱动支持,详见【12.2  注解实现Bean依赖注入】;
  • <bean id="ctxConfig" class="……"/>:直接将使用@Configuration注解的配置类在配置文件中进行Bean定义即可。

3、测试代码如下所示(ConfigurationTest.java)::

 

java代码:
public void testXmlConfig() {
    String configLocations[] = {"chapter12/configuration/xml-config.xml"};
    ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
    Assert.assertEquals("hello", ctx.getBean("message"));
}

 

测试成功,说明通过在基于XML方式的配置文件中能获取到基于Java方式的配置文件中定义的Bean,如“message”Bean。

 

 

12.4.10  基于Java方式的容器实例化

基于Java方式的容器由AnnotationConfigApplicationContext表示,其实例化方式主要有以下几种:

 

 

一、对于只有一个@Configuration注解的配置类,可以使用如下方式初始化容器:

 

java代码:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);

 

二、对于有多个@Configuration注解的配置类,可以使用如下方式初始化容器:

 

 

java代码:
AnnotationConfigApplicationContext ctx1 = new AnnotationConfigApplicationContext(ApplicationContextConfig.class, ApplicationContextConfig2.class);

 

或者

 

java代码:
AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext();
ctx2.register(ApplicationContextConfig.class);
ctx2.register(ApplicationContextConfig2.class);

 

 

三、对于【12.3  注解实现Bean定义】中通过扫描类路径中的特殊注解类来自动注册Bean定义,可以使用如下方式来实现:

 

java代码:
public void testComponentScan() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.scan("cn.javass.chapter12.confiuration");
    ctx.refresh();
    Assert.assertEquals("hello", ctx.getBean("message"));
}

 

以上配置方式等价于基于XML方式中的如下配置:

 

java代码:
<context:component-scan base-package="cn.javass.chapter12.confiuration"/>

 

 

四、在web环境中使用基于Java方式的配置,通过修改通用配置实现,详见10.1.2 通用配置】

 

1、修改通用配置中的Web应用上下文实现,在此需要使用AnnotationConfigWebApplicationContext:

 

java代码:
<context-param>
    <param-name>contextClass</param-name>     
    <param-value>
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    </param-value>
</context-param>

 

 

2、指定加载配置类,类似于指定加载文件位置,在基于Java方式中需要指定需要加载的配置类:

 

java代码:
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        cn.javass.spring.chapter12.configuration.ApplicationContextConfig,
        cn.javass.spring.chapter12.configuration.ApplicationContextConfig2
    </param-value>
</context-param>
  • contextConfigLocation:除了可以指定配置类,还可以指定“扫描的类路径”,其加载步骤如下:

      1、首先验证指定的配置是否是类,如果是则通过注册配置类来完成Bean定义加载,即如通过ctx.register(ApplicationContextConfig.class)加载定义;

      2、如果指定的配置不是类,则通过扫描类路径方式加载注解Bean定义,即将通过ctx.scan("cn.javass.chapter12.confiuration")加载Bean定义。

 

 

原创内容,转载请注明私塾在线【http://sishuok.com/forum/blogPost/list/0/2550.html

19
3
分享到:
评论
1 楼 西斧头帮老大-_- 2016-01-28  
写的真好

相关推荐

    跟我学spring3(8-13)

    【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3 【第十二章】零配置 之 12.5 综合示例-积分商城 ——跟我学spring3 【第十三章】 测试 之 13.1 概述 13.2 单元测试 ——跟我学spring3 ...

    跟我学Spring3(12.4)零配置之基于Java类定义

    跟我学Spring3(12.4)零配置之基于Java类定义Bean配置元数据Java开发Java经验技巧共12页.pdf.zip

    跟我学spring3(8-13).pdf

    11.2 实现通用层 11.3 实现积分商城层 12.1 概述 12.2 注解实现Bean依赖注入 12.3 注解实现Bean定义 12.4 基于Java类定义Bean配置元数据 12.5 综合示例-积分商城 13.1 概述 13.2 单元测试 集成测试 ——跟我学spring3

    JavaEE开发的颠覆者SpringBoot实战[完整版].part3

    而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring Boot实战》从Spring 基础、Spring MVC 基础讲起,从而...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part2

    而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring Boot实战》从Spring 基础、Spring MVC 基础讲起,从而...

    Spring in Action(第二版 中文高清版).part2

    第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送器 12.2.2 构建电子邮件 12.3 调度任务 ...

    Spring in Action(第二版 中文高清版).part1

    第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送器 12.2.2 构建电子邮件 12.3 调度任务 ...

    Spring in Action(第2版)中文版

    第12章访问企业服务 12.1从jndi中获取对象 12.1.1使用传统的jndi 12.1.2注入jndi对象 12.1.3在spring2中注入jndi对象 12.2发送电子邮件 12.2.1配置邮件发送器 12.2.2构建电子邮件 12.3调度任务 12.3.1使用...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part1

    而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring Boot实战》从Spring 基础、Spring MVC 基础讲起,从而...

    从Java走向Java+EE+.rar

    第12章 利用Hibernate访问数据库 157 12.1 ORM——关系-对象映射的概念 157 12.2 Hibernate基础 158 12.2.1 POJO对象 158 12.2.2 Hibernate映射文件 159 12.2.3 Hibernate配置文件 159 12.3 使用...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    第二部分详细讲解了jsf ri、jta、jndi、rmi、jms、javamail、ejb 3的session bean、message driven bean、jpa、jax-ws 2、jaas等java ee知识,这部分知识以jsf+ejb 3+jpa整合开发为重点,通过使用netbeans ide工具...

    Spring-Reference_zh_CN(Spring中文参考手册)

    组成基于XML配置元数据 3.2.3. 多种bean 3.2.3.1. 命名bean 3.2.3.2. 实例化bean 3.2.4. 使用容器 3.3. 依赖 3.3.1. 注入依赖 3.3.1.1. Setter注入 3.3.1.2. 构造器注入 3.3.1.3. 一些例子 3.3.2. 构造器参数的解析...

    Spring 2.0 开发参考手册

    3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ...

    xcode配置iOS 12.4 开发包

    将Xcode适配可以调试、编译、运行、打包系统版本号为iOS 12.4 版本的设备,解决"Could not find Developer Disk Image"问题 使用详情 请前往https://blog.csdn.net/u010731949/article/details/52576792

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    第12章 接口 331 教学视频:29分钟 12.1 自行车带来的问题 331 12.1.1 记录马路上的车辆 331 12.1.2 引发问题的自行车 335 12.1.3 仔细分析recordTransport()方法 338 12.2 初用接口 339 12.2.1 准备好需要...

    Spring中文帮助文档

    3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 ...

    Spring API

    3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 ...

    2020秋八年级数学上册第12章一次函数12.4综合与实践一次函数模型的应用学案无答案新版沪科版

    2020秋八年级数学上册第12章一次函数12.4综合与实践一次函数模型的应用学案无答案新版沪科版

    JAVA程序开发大全---上半部分

    第12章 Struts 2.0的开发及应用 214 12.1 Struts 2.0框架概述 214 12.1.1 Struts 2.0框架工作流程 214 12.1.2 Struts 2.0与Struts 1.x框架的区别 215 12.2 MyEclipse创建基于Struts 2.0框架的项目 215 12.2.1 下载...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    第12章 接口 331 教学视频:29分钟 12.1 自行车带来的问题 331 12.1.1 记录马路上的车辆 331 12.1.2 引发问题的自行车 335 12.1.3 仔细分析recordTransport()方法 338 12.2 初用接口 339 12.2.1 准备好需要...

Global site tag (gtag.js) - Google Analytics