Honeyc's Blog

Spring技术内幕-1

Spring-4种关键策略

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

依赖注入(DI):对象的依赖关系由负责协调系统中各个对象的第三方组件在创建对象时设定。对象无需自行创建或者管理它们的依赖关系-依赖关系将被自动注入到需要它们的对象中去。
面向切面(AOP):分离关注点,每个组件各负责一块特定的功能,诸如日志、事务管理和安全。横切关注点:跨越系统多个组件,将服务模块化,通过声明的方式不去影响系统原有的核心功能,高内聚。

Spring通过应用上下文(ApplicationContext)装载bean的定义并把他们组装起来,全权负责对象的创建和组装。

1
2
3
4
5
6
7
8
//编程式注入
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml
");
//从类路径下
//FileSystemXmlApplicationContext:读取文件系统下
//XmlWebApplicationContext:读取Web应用下的
IntefaceBean bean = (IntefaceBean)context.getBean("beanname");
bean.method();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- beans.xml -->
<!--构造注入-->
<bean id="beanname" class="com.zju.inteface.Bean">
<constructor-arg ref="otherbean">
</bean>
<!-- 工厂方法注入 -->
<bean id="beanname" class="com.zju.inteface.Bean">
<factory-method="getInstance">
</bean>-->
<!-- setter注入 -->
<bean id="beanname" class="com.zju.inteface.Bean">
<property name="parameter" value="value">
<property name="beanname" ref="otherbean">
</bean>
<!-- 内部注入 -->
<!-- setter注入 -->
<bean id="beanname" class="com.zju.inteface.Bean">
<property name="beanname">
<bean class="com.zju.inteface.otherBean" />
</property>
</bean>
<bean id="otherbean" class="com.zju.inteface.otherBean">
</bean>

AOP显示实例,在方法之前或者之后插入功能点方法

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--pointBean包含before和after方法-->
<bean id="pointBean" class="com.zju.inteface.pointBean">
</bean>
<aop:config>
<aop:aspect ref="pointBean">
<!--定义切面-->
<aop:pointcut id="idname" expression="execution(* *)" />
<!--声明后置通知-->
<aop:before pointcut-ref="idname" method="before">
<!--声明前置通知-->
<aop:after pointcut-ref="idname" method="aftetr">
</aop:aspec>
</aop:config>

bean

bean的生命周期
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实现了 InitlializaingBean 接口,Spring将调用它们的afterPropertiesSet()接口方法。bean的init-method也会被调用
8-> 如果bean实了 BeanPostProcessor 接口,Spring将调用它们的postProcessAfterInitialization()接口方法
9-> 到这里,bean已经 准备就绪 ,可被调用并且一直驻留在应用上下文中,直到应用上下文被销毁
10-> 如果bean实现了 DisposableBean 接口,Spring将调用它的destory()接口方法。bean的destory-method会被调用。
bean的作用域

1
2
<bean id="otherbean" class="com.zju.inteface.otherBean" scope="singleton">
</bean>

1、singleton:当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
2、prototype:一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
3、request:在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。
4、session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
5、global session:在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

Spring XML配置

Bean的自动装配

  1. byName:把与Bean的属性具有相同名字(或ID)的其他Bean自动装配到Bean的对应属性中。
  2. byType:把与Bean的属性具有相同类型,多个子类会异常,可指定主要。
  3. constructor:构造器自动装配
  4. autodetect:authowire=”autodetect” spring自动选择装备
  5. 选择注解自动装备,更细粒度。
    : 自动检测,扫描制定包
    为自动检测标注Bean:@Component @Controller @Repository @Service

    @autowired @Inject @Resource
    (1).@autowired
    @Qualifier("oneSubBean")//限定子类的某个bean,限定歧义依赖
    
    (2).@Inject:包含@Autowired的所以功能,并且可以让@Inject注入一个Provider,Provider接口可以实现Bean引用的延迟注入以及注入Bean的多个实例。
    1
    2
    3
    4
    5
    6
    7
    8
    private Set<Bean> beans;
    @Inject
    public SubBean(Provider<Bean> beanProvider){
    beans = new HashSet<Bean>();
    for(int i=0;i<5;i++){
    beans.add(beanProvider.get());
    }
    }