`
klyuan
  • 浏览: 182172 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Spring JavaConfig开发指南(下)

    博客分类:
  • java
阅读更多
lazy
Lazy
延时初始化策略
UNSPECIFIED
 
meta
Meta[]
当前bean的元数据
{}
 
scope
String
Bean的作用域
singleton
Singleton,prototype或自定义作用域
使用纯java方式的bean定义时,处理静态方法时,不再需要-Factory-method
java 代码
  1. @Bean  
  2. public ExampleBean exampleBean() {   
  3.  return ExampleFactory.createBean();   
  4. }   
 
当用方法来定义一个Bean时,这个方法必须是public的。
示例:使用aliases元素。,定义一个Bean,别名为hello
java 代码
  1. @Bean(aliases={"hello"})   
  2. public HelloWorld helloWorld(){   
  3. HelloWorld helloWorld = new HelloWorld();   
  4. helloWorld.setWord(word());   
  5. return helloWorld;   
  6. }   
  7.     
 
 
java 代码
  1. public static void main(String[] args){   
  2. ApplicationContext context = new AnnotationApplicationContext(ConfigurationFull.class.getName());   
  3. HelloWorld hello = (HelloWorld)context.getBean("hello");   
  4. hello.sayHello();   
  5.   
  6. }   
 
1.1 @ExternalBean
指定Bean是一个外部Bean
 示例:
java 代码
  1. @Configuration  
  2. public abstract class ExternalConfiguration {   
  3.        
  4. @ExternalBean  
  5. public abstract HelloWorld helloWorld();   
  6. }   
 
java 代码
  1. public class ConfigurationWithExternal {   
  2.  public static void main(String[] args){   
  3.  ApplicationContext context = new AnnotationApplicationContext(ConfigurationFull.class.getName(),ExternalConfiguration.class.getName());   
  4.  HelloWorld hello = (HelloWorld)context.getBean("helloWorld");   
  5.  hello.sayHello();   
  6.  }   
  7. }   
 
这里,在ExternalConfiguration中定义的helloWorld自动会被,在ConfigurationFull中定义的helloWorld覆盖。
所以,@ExtenalBean的意思是,这个是在父Context中定义的,这个父context可以是一个Configuration或是一个外部的xml文件。使用这个注释的好处是为了保持重构友好。
 
 
1.2 @ScopedProxy
 
Spring通过scoped proxies提供了一个方便的作用域依赖的处理方法。最简单的方式就是创建一个代理。在当使用xml配置时,使用<aop:scoped-proxies></aop:scoped-proxies>元素。JavaConfig提供了一个等价物就是@ScopedProxy,它提供了<aop:scoped-proxies></aop:scoped-proxies>相同的语义和配置选项。
java 代码
  1. @Bean(scope = DefaultScopes.SESSION)   
  2. @ScopedProxy  
  3. public UserPreferences userPreferences() {   
  4.    return new UserPreferences();   
  5. }   
  6.     
  7. @Bean  
  8. public Service userService() {   
  9.    UserService service = new SimpleUserService();   
  10.    // a reference to the proxied 'userPreferences' bean   
  11.    service.seUserPreferences(userPreferences());   
  12.    return service;   
  13. }   
一个userPreferences的Bean定义了Session的作用域,一个为singleton作用域的Bean userService注入了这个bean userPreferences.因为userSerivce只会被实例化一次,理论上它只会操纵一个userPreferences对象。而我们是希望它每次去从session中取回一个userPreferences对象。所以这就需要一个代理。这个代理总会在我们需要使用userPreferences对象时,自动去从session中取回userPreferences对象。
<aop:scoped-proxies></aop:scoped-proxies>及@ScopedProxy就是提供了这样的功能。
 
2.           Bean的可见度
     JavaConfig有一个非常好的特性就是可以控制Bean的可见度。JavaConfig可以使用Java方法的可见度修饰符来决定Bean是否可以被Application Context 和Bean Factory访问
java 代码
  1. @Configuration  
  2. public class VisibilityConfiguration {   
  3.     
  4.  @Bean  
  5.  public UserInfo publicUserInfo(){   
  6.      UserInfo user = new UserInfo();   
  7.      user.setName(protectedName());   
  8.      user.setAddres(privateAddres());   
  9.      return user;   
  10.  }   
  11.  @Bean  
  12.  protected String protectedName(){   
  13.      String name = "jack";   
  14.      return name;   
  15.  }   
  16.     
  17.  private String privateAddres(){   
  18.      String addres= "Beijing";   
  19.      return addres;   
  20.  }   
  21. }   
上面三个由方法定义的Bean中,方法分别为public ,protected,private。
java 代码
  1. public class ConfigurationWithVisibility {   
  2.  public static void main(String[] args){   
  3.      ApplicationContext context = new AnnotationApplicationContext(VisibilityConfiguration.class.getName());   
  4.      UserInfo user = (UserInfo)context.getBean("publicUserInfo");   
  5.      String name = (String)context.getBean("protectedName");   
  6.      String addres = (String)context.getBean("privateAddres");   
  7.         
  8.  }   
  9. }   
 
 
当我们在Context中访问"protectedName"或"privateAddres"时都会抛出异常
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'protectedName' is defined
 
但是在VisibilityConfiguration内部,三个Bean是相互可以访问的。
所以如果在用@Bean注释的方法,如果不是public的,是不能被外部的ApplicationContext访问的。
JavaConfig 提供了Bean的可见度功能,利用Spring提供的层级应用上下文,用一个特殊的Configuration类来放置所有的隐藏Bean,在一个子应用上下文内,隐藏Bean能够访问父应用上下文定义的Bean。而父应用上下文的Bean却不能访问子应用上下文的隐藏Bean.
 
3.            Bean的依赖设置
装配一个Bean,最简单的方法就是java提供的构造函数
java 代码
  1. @Bean(scope=DefaultScopes.PROTOTYPE)   
  2. public UserInfo userInfo(){   
  3.     UserInfo user = new UserInfo();   
  4.     user.setName(name());   
  5.     return user;   
  6. }   
  7. @Bean(scope=DefaultScopes.SINGLETON)   
  8. public String name(){   
  9.     String name = "jack";   
  10.     return name;   
  11. }   
 
Bean之间依赖的设置通过bean的方法名来进行设置,并不是通过bean名称。
Name()方法被@Bean注释后,它的Bean名称是name,但是在userInfo方法,来设置name属性是仍然需要使用方法名name(),而不是bean名称name.
 
java 代码
  1. 当使用@Bean标记后,Bean都会由Spring容器进行管理。UserInfo声明为prototype,而name声明为singleton.   
  2.      ApplicationContext context = new AnnotationApplicationContext(VisibilityConfiguration.class.getName());   
  3.      UserInfo user = (UserInfo)context.getBean("userInfo");   
  4.      UserInfo user2 =(UserInfo)context.getBean("userInfo");   
  5.      System.out.println(user == user2);   
  6.      String name = (String)context.getBean("name");   
  7.      String name2 = (String)context.getBean("name");   
  8.      System.out.println(name == name2);   
  9.     
输出结果:
false
true
 
可见,被@Bean标记后,每次从ApplicationContext中获得的userInfo的对象都不是同一个对象。而每次获得的name的对象都是同一个对象。
 
4.           使用JavaConfig
   我们在前面的例子,已经多次看到了AnnotationApplicationContext的使用。现在来全面介绍AnnotationApplicationContext.
AnnotationApplicationContext提供了四个构造函数。
1.public AnnotationApplicationContext(java.lang.Class... classes)
可以把多个Configuration类构造成一个ApplicationContext
2. public AnnotationApplicationContext(java.lang.String... locations)
 除了可以接收多个完整的Configuration类构造成一个ApplicationContext外,还可以接改ant风格的类路径。
 例如:ApplicationContext context = new AnnotationApplicationContext(ConfigurationFull.class.getName(),ExternalConfiguration.class.getName());
 
ApplicationContext context = new AnnotationApplicationContext("**/configuration/*Configuration.class");
 
3.public  AnnotationApplicationContext(org.springframework.context.ApplicationContext parent)
给定一个父ApplicationContext来构造一个AnnotationApplicationContext.
 
4. public AnnotationApplicationContext()
一个默认的构造函数
 
上面这些都是针对Configuration类的。而我们更多的时候需要与xml结合进行使用。
这就需要使用到org.springframework.config.java.process.ConfigurationPostProcessor.
java 代码
  1. <!---->"1.0" encoding="UTF-8"?>   
  2. <!---->"-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">   
  3.   
  4. <beans></beans>  
  5.   class="com.springconfig.example.chapter3.ConfigurationFull">   
  6.        
  7.   class="org.springframework.config.java.process.ConfigurationPostProcessor"/>     
  8.   
java 代码
  1. public static void main(String[] args){   
  2.     ApplicationContext context = new ClassPathXmlApplicationContext("com/springconfig/example/chapter3/applicationContext.xml");   
  3.     String word = (String)context.getBean("word");   
  4.     System.out.println(word);   
  5. }   
  6. }   
程序运行结果
HelloWorld!
 
注意,外部的xml可以直接使用Configuration中配置的Bean,而Configuration中的Bean需要使用Xml中的Bean,则需要使用@External注释。
 
 
 
 
5.           Bean的命名策略
使用JavaConfig由方法产生的Bean,其方法名就是Bean名称。但是当多个方法重名,或者有多个Congiguration或与外部xml混用时,这种方式并不合适。不同的类全覆盖彼此的定义。为了自定义bean名称产生的行为,可以能过实现BeanNamingStrategy 接口来提供它自己的bean名称产生策略
 
BenaNamingStrategy有一个默认的实现MethodNameStrategy
 
MethodNameStrategy提供了一个prefix属性,用于指定Bean的前辍的产生方式
Prefix有三个取值。
NONE:即没有前辍,仍然使用方法名作为Bean的名称。
CLASS:使用类名称为作Bean的前辍,中间以.号相连。如:ConfigurationFull.word
FQN:使用完整的类路径作为Bean的前辍。如:com.springconfig.example.chapter3.ConfigurationFull.word
 
下面就这三种方式进行说明:
java 代码
  1. <!---->"1.0" encoding="UTF-8"?>   
  2. <!---->"-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">   
  3.   
  4.   
  5. <beans></beans>  
  6.   class="com.springconfig.example.chapter3.ConfigurationFull">   
  7.        
  8.   class="org.springframework.config.java.process.ConfigurationPostProcessor">   
  9.     "namingStrategy">   
  10.       class="org.springframework.config.java.naming.MethodNameStrategy">   
  11.           "prefix" value="CLASS"/>   
  12.          
  13.        
  14.      
  15.   
java 代码
  1. public static void main(String[] args){   
  2.     ApplicationContext context = new ClassPathXmlApplicationContext("com/springconfig/example/chapter3/applicationContext.xml");   
  3.     String word = (String)context.getBean("ConfigurationFull.word");   
  4.     System.out.println(word);   
  5. }   
  6. }   
 
程序输出:
HelloWorld!
 
把上面的prefix属性值换成FQN
java 代码
  1. public static void main(String[] args){   
  2.     ApplicationContext context = new ClassPathXmlApplicationContext("com/springconfig/example/chapter3/applicationContext.xml");   
  3.     String word = (String)context.getBean("com.springconfig.example.chapter3.ConfigurationFull.word");   
  4.     System.out.println(word);   
  5. }   
程序输出:
HelloWorld!
6.           注释还是XML
 Spring因为XML大量使用而受到了越来越多的批评,也使得基于Spring的项目变得越来越复杂。使用XML来配置Bean,它无法进行类型安全检查,当类名称或方法名被改名之后,XML中的相应配置无法随之改变。这对项目的重构带来了极大的不方便。随着JAVA EE 5,JAVA EE 6的相继推出,其中一个最大的特性就是注释的使用。当Spring使用注释来Bean时,就可以在一个纯java的类中配置Bean.因为是在纯java的环境中,可以获得编译期类型安全检查的好处,当Bean的类名或方法名进行重构修改后,Configuration中的相应的定义会被同时修改。
 JavaConfig就是为了简化Spring项目的产生的,JavaConfig的使用也非常的简单,可见JavaConfig应该是简化Spring项目的一种最好解决方式。但是并不意味着,JavaConfig就应该完全的取代xml配置。Xml的优势是就是配置的灵活性和参数化以及访问外部环境,以及在web系统中的应用。JavaConfig并不排斥xml,相反,它可以和xml很好的相结合,来降低spring项目开发的复杂度。在未来,xml应该会成为JavaConfig的补充。
 
7.           关于文档
  该文档是一个全免费的文档,可以免费传播。引用请获得作者的同意!
分享到:
评论
2 楼 山风小子 2007-06-08  
> 引用请获得作者的同意!

写的很好,就是小气了点,
开玩笑的
1 楼 klyuan 2007-06-07  
快沉了啊

相关推荐

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

    在当今Java EE 开发中,Spring 框架是当之无愧的王者。而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1 系统概述 13.2 需求分析 13.2.1 系统用例图 ...

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

    在当今Java EE 开发中,Spring 框架是当之无愧的王者。而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1 系统概述 13.2 需求分析 13.2.1 系统用例图 ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1 系统概述 13.2 需求分析 13.2.1 系统用例图 ...

    spring.net中文手册在线版

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NET以Java版的Spring框架为...

    springCloud

    Spring Cloud简介 Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud0 CloudFoundry、Spring Cloud AWS、Spring Cloud ...

    免费下载:自己整理的java学习资料

    自己整理的一些资料,不需要积分,希望对大家有帮助。 里面包有如下的一些java资料 Ant使用指南.pdf cvs.pdf Eclipse入门-- Eclipse的使用简介及插件开发.PDF ...spring2中文开发参考手册.chm a.txt

    ibatis 开发指南(pdf)

    ibatis 开发指南 ibatis Quick Start............................................................................................ 5 准备工作...........................................................

    《程序天下:J2EE整合详解与典型案例》光盘源码

    12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1 系统概述 13.2 需求分析 13.2.1 系统用例图 ...

    java基于ssm的列车火车高铁票务信息管理系统 毕业设计源码论文

    本文以java为开发技术,实现了一个列车票务信息管理系统。列车票务信息管理系统的主要使用者分为管理员;个人中心、用户管理、车票信息管理、购票指南管理、管理员管理、论坛管理、我的收藏管理、系统管理、订单管理...

    webx3框架指南PDF教程附学习Demo

    现在有很多Java的Web框架可供选择,并且它们也都是免费的。例如: • Struts • Webwork • Tapestry • Spring MVC 以上框架都是非常优秀的。说实话,如果阿里巴巴网站在2001年开始,就有这么多可选择的话,...

    java_技术参考汇集(完整版)

    config struts标签 ant使用指南 cvs eclipse开发、插件 hibernate javaAnnotation java配置文件编写说明 java设计模式 jboss log4j spring starts——actiong struts标签 swing tomcat webandxml 正则表达式…………...

    单点登录源码

    ├── zheng-config -- 配置中心[端口:1001] ├── zheng-upms -- 用户权限管理系统 | ├── zheng-upms-common -- upms系统公共模块 | ├── zheng-upms-dao -- 代码生成模块,无需开发 | ├── zheng-upms-...

    java ssm新生入学报到管理系统毕业设计项目源码含论文和ppt

    这是新款的基于B/S和Web开发的JavaWeb的SSM(Spring+SpringMVC+MyBatis)源码,包含源码数据库论文答辩ppt等,开发工具Idea支持eclipse,MySQL功能也比较全面,比较适合作为毕业设计使用,感兴趣的朋友可以下载看看 ...

    product-flow

    -用JavaConfig替换大多数XML配置文件以更好地维护 -仅保留XML文件作为Webflow的描述器,从而合理地更好地理解业务流程 -在JPA查询中使用多种方法,可以灵活地满足各种业务需求并有效地进行编程 -与JSP相比,展示了...

    asp.net知识库

    asp.net 2.0下嵌套masterpage页的可视化编辑 C# 2.0与泛型 动态调用对象的属性和方法——性能和灵活性兼备的方法 泛型技巧系列:用泛型打造可复用的抽象工厂 泛型技巧系列:如何提供类型参数之间的转换 .NET 2.0 ...

Global site tag (gtag.js) - Google Analytics