收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:3934439
访问用户量:4236
笔记经验:
总积分:261656
级别:VIP5
搜索本笔记
ta的交流分类
ta的交流主题贴(325)
ta的所有交流贴(824)
ta的全部笔记
全部笔记(137)
未分类笔记(0)
Java Web(8)
并发实践(1)
课程问题(0)
Java(22)
架构(1)
缓存(5)
JavaEE(0)
JVM(7)
跟我学spring3(52)
Spring Sec……(3)
Spring 3.x……(4)
Spring Sec……(3)
跟开涛学Spring……(14)
深入剖析Spring……(10)
性能调优(6)
前端(1)
Tomcat源码解读(0)
spring sec……(0)
存档
2014-01(3)
2013-12(8)
2012-10(4)
2012-09(2)
2012-08(15)
2012-07(9)
2012-06(0)
2012-05(7)
2012-04(1)
2012-03(3)
2012-02(43)
2011-11(16)
2011-10(26)

2012-02-23 15:21:50
【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3
浏览(26900)|评论(0)   交流分类:Java|笔记分类: 跟我学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

相关笔记推荐
精品视频课程推荐

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

ssh+jbpm项目(某集团OA)视频教程
达到能综合使用Struts2+Spring3+Hibernate3+Jbpm4来进行实际项目开发的能力。 包括:ssh和jbpm的整合;数据字典;通用DAO(Spring+Hibernate+泛型+反射+SpEL+模板方法模式);自动生成UUID的加强版;分层开发、SSH联合的基本开发;翻页的taglib;示范真实值和表现值,数据参照的实现;文件上传下载;主子表操;登录验证码;登录控制的拦截器

深入浅出学Spring Web MVC视频教程
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识

Weblogic实战视频教程
WebLogic基础知识:WebLogic基本概念、正确安装WebLogic、建域、应用部署于JDBC选择、对WebLogic的监控和日志查看、集群的高可用性;课程目标:彻底掌握WebLogic的基本概念,在理解基本概念的基础上做到正确的安装WebLogic,根据不同的需求创建域,合理选择应用部署和JDBC配置。熟练掌握WebLogic的console监控,了解各种性能和运行指标,以及对监控结果的分析,运用集群的高可用性,对集群架设。

深入浅出学Spring Data JPA视频教程
系统、完整的学习Spring Data JPA开发的知识。包括:Spring Data JPA入门;JpaRepository基本功能 ;JpaRepository的查询;客户化扩展JpaRepository;Specifications查询。

浏览(26900)|评论(0)   交流分类:Java|笔记分类: 跟我学spring3

评论(0)
请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网