Spring初识

spring的出现根本理念是为了简化java的开发.为了降低java开发的复杂性,spring采用了以下4个策略:

1.基于POJO的轻量级和最小侵入性编程.
2.通过依赖注入和面向接口实现松耦合.
3.基于切面和惯例进行声明式编程.
4.通过切面和模板减少样板式代码.

依赖注入

Spring通过应用上下文装载Bean的定义,并把它们组装起来,Spring山下文全权负责Bean的创建和组装.Spring自带了几种应用上下文的实现,它们之间的区别仅仅是如何加载它们的配置.
如果Bean是在xml文件中定义的,选择ClassPathXmlApplicationContext作为应用上下文是比较合适的.该类加载位于系统ClassPath下的一个或者多个XML配置文件.

1
2
3
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
XXX xxx = (XXX)context.getBean("XXX") ;
...

应用切面

依赖注入让相互协作的组件保持松散耦合,而AOP允许你把遍布各处的功能分离出来形成可重用的组件.
不同组件往往有些系统功能,诸如安全,事物管理,日志这些系统服务需要注入到不同具有核心业务功能的组件中去,这些系统服务通常被称为横切关注点.
这些横切关注点会给组件带来双重复杂性.
AOP使这些服务模块化,并以声明的方式将其应用到它们需要影响的组件中去.总之,AOP保证POJO保持简单.
声明一个切面的例子:

 <!--声明一个切面  --> 
<bean id="resting" class="com.mj.springAction.Resting" />
<aop:config>
    <aop:aspect ref="resting">
    <aop:pointcut expression="execution(* *.companyEarn(..))" id="work"/>
    <aop:before pointcut-ref="work" method="beforeWork"></aop:before>
    <aop:after pointcut-ref="work" method="afterWork"></aop:after>
   </aop:aspect>
</aop:config>

使用模板消除样板式代码

使用jdbcTemplate这些避免模板式代码,影响整体代码逻辑.

容纳你的bean

Spring容器使用依赖注入管理应用组件.
Spring容器分为2类,Bean工厂和应用上下文.Bean工厂由org.springframework.beans.factory.BeanFactory 接口定义 .
是最简单的容器,提供基本的DI支持.
应用上下文由org.springframework.context.ApplicationContext,基于beanFactory之上构建,并提供面向应用的服务,例如从属性文件解析文本信息的能力,以及发布应用事件给感兴趣的事件监听器的能力.
实际中往往多使用应用上下文.因为封装比Bean工厂更高级.

与应用上下文共事

Spring自带了几种应用上下文,下面几种是最常用到的:

  • ClassPathXmlApplicationContext—从类路径下的xml配置文件中加载上下文定义,把应用上下文定义文件当做类资源.
  • FileSystemXmlApplicationContext—读取文件系统下的XML配置文件并加载上下文定义.
  • XmlWebApplicationContext—读取web应用下的Xml配置文件并加载上下文定义.
    FileSystemXmlApplicationContext和classPath加载相似:
    ApplicationContext context =new FileSystemXmlApplicationContext("c:/foo.xml") ;

    Bean的生命周期

    传统的Java应用中,使用new实例化Bean,就可以使用该Bean了.不再使用时,由gc自动垃圾回收.
    而Spring就相对细腻许多.
    Alt text
    描述就是:
  1. Spring对bean进行实例化.
  2. Spring将值和bean的引用注入进Bean对应的属性中.
  3. 如果Bean实现了BeanNameAware接口,Spring将Bean的Id传入setBeanName()接口方法.
  4. 如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()接口方法,将BeanFactory容器实例传入.
  5. 如果Bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()接口方法,将应用上下文的引用传入.
  6. 如果Bean实现了BeanPostProcessor接口,Spring将调用postProcessBeforeInitialization()接口方法.
  7. 如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法,类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用.
  8. 如果Bean实现了BeanPostProcessor接口,Spring将调用postProcessAfterInitialization()接口方法.
  9. 此时此刻,Bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁.
  10. 如果Bean实现了DisposableBean接口,Spring将调用它的destory()方法.同样,如果Bean使用destory-method声明了销毁方法,该方法也会被调用.

一个完整的例子

Humans.java

1
2
3
4
5
6
7
8
9
10
11
package com.mj.springAction;
/**
* 人类
* @author mingjing
*
*/
public interface Humans {
public void life() ;
public void work() ;
}

OrdinaryMen .java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.mj.springAction;
import org.springframework.beans.factory.annotation.Required;
public class OrdinaryMen implements Humans {
private String name ;
public String getName() {
return name;
}
@Required
public void setName(String name) {
this.name = name;
}
public void life() {
System.out.println(this.name+" `s life is hard.") ;
}
public void work() {
System.out.println(this.name+" `s work is tired.") ;
}
}

Resting.java

1
2
3
4
5
6
7
8
9
10
11
package com.mj.springAction;
public class Resting {
public void beforeWork(){
System.out.println("Lalala,people need to eat some thing before work!");
}
public void afterWork(){
System.out.println("Hohoho,people need to eat some thing or have a sleep afer work!") ;
}
}

CompanyMainTest .java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.mj.springAction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CompanyMainTest {
public static void main(String[] args) {
//ApplicationContext context =new FileSystemXmlApplicationContext("c:/foo.xml") ;
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-action-config/spring-beans.xml");
Companys company = (Companys)context.getBean("companys") ;
company.companyEarn();
}
}

bean配置文件:spring-beans.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<bean id="companys" class="com.mj.springAction.Companys">
<constructor-arg ref="ordinaryMen" />
</bean>
<bean id="ordinaryMen" class="com.mj.springAction.OrdinaryMen" >
<property name="name" ref="name"/>
</bean>
<bean id="name" class="java.lang.String">
<constructor-arg index="0" value="xiaoming"/>
</bean>
<!--声明一个切面 -->
<bean id="resting" class="com.mj.springAction.Resting" />
<aop:config>
<aop:aspect ref="resting">
<aop:pointcut expression="execution(* *.companyEarn(..))" id="work"/>
<aop:before pointcut-ref="work" method="beforeWork"></aop:before>
<aop:after pointcut-ref="work" method="afterWork"></aop:after>
</aop:aspect>
</aop:config>

热评文章