Spring 之 注册LoadTimeWeaver

Spring使用LoadTimeWeaver当将类加载进JVM时进行动态转换。

为了使得加载时间织入,在你的@Configuration类上加入@EnableLoadTimeWeaving


@Configuration
@EnableLoadTimeWeaving
public class AppConfig {

}


或者是使用元素context:load-time-weaver



    

只要配置了ApplicationContext。ApplicationContext中的任何Bean可能实现LoadTimeWearveAware,从而接受load-time weaver 实例的引用。与Spring 的JPA一起使用是很有用的。这里load-time weaving对于JPA 类转换是很必要的。详情参考LocalContainerEntityManagerFactoryBean的doc文档。对于更多详情参考Section 9.8.4, “Load-time weaving with AspectJ in the Spring Framework”.


5.15 ApplicaitionConetext的额外功能


如本章所讲,org.springframework.beans.factory包提供了基本函数管理和操作beans,也包含了编程的方式。org.springframework.context包添加了ApplicationContext接口,其继承了BeanFactory接口,也继承了其他的接口从而添加额外的功能。许多使用者一般以申明的方式使用ApplicationContext,而不是程序化编程,但是作为替代依赖支持类比如ContextLoader自动实例化一个ApplicationContext,其作为JavaEE web应用程序启动过程的一部分。


为增强BeanFactory功能,Context包也提供了其他的功能:

  •  通过MessageSource接口以i18n方式访问消息
  • 通过ResourceLoader接口访问资源,比如URLs和文件
  • 实现ApplicationListener接口 事件发布给bean,通过ApplicationEventPublisher接口
  • 加载多个(分层的)上下文,通过HierarchicalBeanFactory接口,允许每个专注一个特殊层,比如应用程序的web层。


5.15.1 使用MessageSource国际化

ApplicationContext接口继承了MessageSource接口,并且提供了国际化功能。Spring也提供了HierarchicalMessageSource接口,这样可以分层的解决消息。这个接口一起提供了这样的功能:Spring可以影响消息的resolution。这些接口包含了如下方法:

  • String getMessage(String code, Object[] args, String default, Locale loc):这个基本方法从MessageSource接收消息。当没有从指定的locate中找到消息时,就使用默认的消息。传递的参数变成默认的值,标准包提供MessageSource功能
  • String getMessage(String code, Object[] args, Locale loc):基本上与前面的方法相同,但是也有区别:没有指定默认的消息;如果没有找到消息,抛出NoSuchMessageException异常
  • String getMessage(MessageSourceResolvable resolvable, Locale locale):前面方法中的参数属性全部封装类MessageSourceResolvable中。


当加载一个ApplicationContext,其自动查找Context中的MessageSource bean。这个bean必须有名字messageSource。如果没有发现找到这样的bean,调用前面的方法委托给消息源(message source)。如果没有找到消息源,ApplicationContext找其有相同名字messageSource的上一级类。如果找到了,以MessageSource使用这个bean。如果ApplicationContext没有找到消息来源,实例化一个空的DelegatingMessageSource获取上述方法的调用。


Spring提供了两个MessageSource的实现,ResourceBundleMessageSource和StaticMessageSource。两者都实现了HierarchicalMessageSource来嵌入消息。StaticMessageSource仅提供编程的方式将消息添加到源中。下面是ResourceBundleMessageSource用法的例子:



    
        
            
                format
                exceptions
                windows
            
        
    

在这个例子中,假定在你的classpath中定义了三个资源,分别为format,exceptions,windows。任何处理消息的请求都将通过ResourceBundles的处理消息的的JDK标准方式处理。下面给出了上述资源文件的内容:


# in format.properties
message=Alligators rock!
# in exceptions.properties
argument.required=The {0} argument is required.


执行MessageSource功能的的程序将在下一个例子中演示。记住所有的ApplicationContext实现也是MessageSource实现,所以其类型可以转化为MessageSource接口。


public static void main(String[] args) {
    MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
    String message = resources.getMessage("message", null, "Default", null);
    System.out.println(message);
}

上述程序的结果输出为:
Alligators rock!



综上所述,MessageSource被定义为一个beans.xml的文件,存在于系统路径的根目录下。messageSource bean定义通过其beannames属性涉及到大量的资源束。列表中传递的三个文件,其对应着beannames属性位于系统路径的根目录并且分别称作format.property,exception.property和windows.property。


下一个例子显示了传递给消息查找的参数。这些参数将转化为String类型并且插入到查找信息的占位符中。





    
    
        
    

    
    
        
    


public class Example {

    private MessageSource messages;

    public void setMessages(MessageSource messages) {
        this.messages = messages;
    }

    public void execute() {
        String message = this.messages.getMessage("argument.required",
            new Object [] {"userDao"}, "Required", null);
        System.out.println(message);
    }

}


调用execute()方法的输出结果如下:

The userDao argument is required.

关于国际化,Spring不同的MessageResource实现遵循相同的locate resolution并且以标准JDK的ResourceBundle遵循规则。简而言之,还是以前面的例子messageResource为例子,如果你想定义en-GB的本地化,你将分别创建format_en_GB.properties, exceptions_en_GB.properties,和windows_en_GB.properties三个文件。



一般地,locate resolution 由应用程序的周遭环境决定。在这个例子中,英语本地化消息将手动指定。


# in exceptions_en_GB.properties
argument.required=Ebagum lad, the {0} argument is required, I say, required.

public static void main(final String[] args) {
    MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
    String message = resources.getMessage("argument.required",
        new Object [] {"userDao"}, "Required", Locale.UK);
    System.out.println(message);
}


上述程序打印结果如下:


Ebagum lad, the userDao argument is required, I say, required.


你也可以使用MessageSourceAware接口获取任何已定义MessageResource的依赖。任何定义在一个ApplicationContext中的任何bean,其已经实现了MessageSourceAware接口,当创建和配置bean时,将注入到应用程序上下文的MessageResource。



注意:作为可选的ResourceBundleMessageSource,Spring提供了ReloadableResourceBundleMessageSource类。这个变体支持相同的束文件格式,但是比基于标准JDK的ResourceBundleMessageSource实现更加灵活。尤其是,其允许从Spring的任何资源位置读取文件,而不仅仅是类路径,并且支持从束属性文件的热加载(需要高效缓存它们时)。

 

你可能感兴趣的:(Spring)