Spring in Action(一) Core Spring:Spring into Action(2)

Spring的核心是dependency injection (DI) and aspect-oriented programming (AOP).

第一章概览一下什么是Spring,以及DI和AOP是怎么解耦(decoupling )应用组件的。

第二章讲模块、bean怎么连接起来,我们会了解spring提供的三种配置方式:自动配置,基于java的配置和用xml配置。【wiring beans,不清楚标准翻译法,暂翻译为连接,装配,反正大概就是这个意思】

第三章延续第二章讲一些高级的技术技巧,包括带有特定条件的配置,自动装配时的歧义处理,域,以及Spring表达式语言。【Spring Expression Language)】

第四章讲Spring的AOP如何解耦全路服务(比如安全控制及审计)decouple system-wide services (such as security and auditing)  】


1.2 bean容器

基于Spring的应用的对象是通过Spring container 来管理的,包括创建,装配,配置和管理生命周期。

分两大类,Bean factories(接口定义在org.springframework.beans.factory.BeanFactory )是最简单的容器,提供简单的DI支持。Application contexts (接口定义在org.springframework.context.ApplicationContext )提供应用框架服务,比如从properties文件解析文字消息,向相关listeners发布events等。

 

1.2.1 application context 

  • AnnotationConfigApplicationContext 从一个或多个基于java的配置类加载一个Spring application context
  • AnnotationConfigWebApplicationContext 同上,加载的是Spring web application context
  • ClassPathXmlApplicationContext 从一个或多个作为classpath资源的xml文件加载一个content defination
  • FileSystemXmlApplicationContext 从一个或多个文件系统中的xml文件加载一个context defination
  • XmlWebApplicationContext 从一个web应用中的一个或多个xml文件加载content definations

  关于web的以后再说。先看其他三个:

 

 1 public class ApplicationContextTest {
 2     public static void main(String[] args) {
 3         ApplicationContext context = new FileSystemXmlApplicationContext("D:/test/knight.xml");
 4         Knight knight = context.getBean(Knight.class);
 5         System.out.println(knight);
 6         knight.embarkOnQuest();
 7 
 8         context = new ClassPathXmlApplicationContext("META-INF/spring/knight.xml");
 9         knight = context.getBean(Knight.class);
10         System.out.println(knight);
11         knight.embarkOnQuest();
12 
13         context = new AnnotationConfigApplicationContext(KnightConfig.class);
14         knight = context.getBean(Knight.class);
15         knight.embarkOnQuest();
16 
17     }
18 }

 

你会发现第三个运行时没有切面,因为我们在xml里声明了切面而config里没有,需要做如下修改:

 1 @Configuration
 2 @EnableAspectJAutoProxy
 3 public class KnightConfig {
 4     @Bean
 5     public Knight knight(){
 6         return  new BraveKnight(quest());
 7     }
 8 
 9     @Bean
10     public Quest quest() {
11         return new SlayDragonQuest(System.out);
12     }
13 
14     @Bean
15     public Minstrel minstrel(){
16         return new Minstrel(System.out);
17     }
18 }
 1 @Aspect
 2 public class Minstrel {
 3     private PrintStream printStream;
 4 
 5     public Minstrel(PrintStream printStream) {
 6         this.printStream = printStream;
 7     }
 8 
 9     @Pointcut("execution(* *.embarkOnQuest(..))")
10     public void performance() {
11     }
12 
13     @Before("performance()")
14     public void singBeforeQuest() {
15         printStream.println("Fa la la, the knight is so brave");
16     }
17 
18     @After("performance()")
19     public void singAfterQuest() {
20         printStream.println("Tee he he, the brave knight did embark on a quest");
21     }
22 }

注意不要丢了注解。注解名可读性都很强,基本能够解释它是做什么的,运行刚才的测试类,发现一切正常。OK。

1.2.2 bean的一生

测试一下:

 1 public class ANonsense implements Nonsense, BeanNameAware, BeanFactoryAware,ApplicationContextAware ,BeanPostProcessor,InitializingBean,DisposableBean{
 2     private static int i = 0;
 3 
 4     private String property;
 5     private String id;
 6     private BeanFactory beanFactory;
 7     private ApplicationContext applicationContext;
 8 
 9     public void printOrder(String methodName,Object...params) {
10         System.out.println("method " + methodName + " called at the order " + i++);
11         ArrayList<Object> paramList = new ArrayList<>(params.length);
12         Collections.addAll(paramList,params);
13         System.out.println("params :" + paramList);
14     }
15 
16     public ANonsense(String property) {
17         this.property = property;
18         printOrder("constructor");
19     }
20 
21     @Override
22     public void setBeanName(String id) {
23         this.id = id;
24         printOrder("setBeanName",id);
25     }
26 
27     @Override
28     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
29         this.beanFactory = beanFactory;
30         printOrder("setBeanFactory",beanFactory);
31     }
32 
33     @Override
34     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
35         this.applicationContext = applicationContext;
36         printOrder("setApplicationContext",applicationContext);
37     }
38 
39     @Override
40     public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
41         printOrder("postProcessBeforeInitialization",o,s);
42         return o;
43     }
44 
45     @Override
46     public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
47         printOrder("postProcessAfterInitialization",o,s);
48         return o;
49     }
50 
51     @Override
52     public void nonsenseMethod() {
53         System.out.println("use the bean");
54     }
55 
56     @Override
57     public void afterPropertiesSet() throws Exception {
58         printOrder("afterPropertiesSet");
59     }
60 
61     public void init(){
62         printOrder("init");
63     }
64 
65     @Override
66     public void destroy() throws Exception {
67         printOrder("destory");
68     }
69 }
View Code
 1 public class NonsenseTest {
 2     public static void main(String[] args) {
 3         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/nonsense.xml");
 4         Nonsense nonsense = context.getBean(Nonsense.class);
 5         nonsense.nonsenseMethod();
 6 
 7         CompactDisc d = context.getBean(CompactDisc.class);
 8         d.play();
 9         context.close();
10 
11     }
12 }

结果可能跟上图有一些出入,具体原因可能要在以后慢慢了解了,目前我们要知道的事是:bean在container中有生命周期,他们的调用是有一定顺序的,在使用时一定要注意这个顺序。

初始化先配属性,然后是名字、工厂、上下文,BeanPostProcessor包了两个,一个是InitializingBean的afterPropertiesSet() ,一个是配置的init方法。这里要特别注意下BeanPostProcessor并没有直接包在init方法两边,而是放了一个afterPropertiesSet() 方法进来,这一点是比较容易让人困惑的,所以要特别注意下。

1.2.3 spring地图

一些网站:

http://projects.spring.io/spring-webflow/

http://docs.spring.io/spring-ws/site/

http://projects.spring.io/spring-security/

http://projects.spring.io/spring-integration/

http://projects.spring.io/spring-batch/

http://projects.spring.io/spring-android/

 

posted @ 2017-06-16 10:11  剑侠飞蓬  阅读(414)  评论(0编辑  收藏  举报