Spring2学习笔记(1)
来源:互联网 发布:淘宝美工自我评价 编辑:程序博客网 时间:2024/05/18 06:21
最近看完了<<spring in action(第二版)>>,感觉写得确实经典,本人将在接下来的时间来分享个人的学习笔记,内容可能不是太丰富,只是对一些知识点的总结,如果要详细学习的,建议大家去看这本书
1 基本Bean装配
1.1 Spring容器
1、 Bean工厂
(org.springframework.beans.factory.BeanFactory接口定义),提供了基础的依赖注入
BeanFactory factory =
new XmlBeanFactory(new ClassPathResource("hello.xml"));
GreetingService greetingService=
(GreetingService) factory.getBean("greetingService");
2、 应用上下文
org.springframework.context.ApplicationContext
ApplicationContext ctx =
new ClassPathXmlApplicationContext(
"com/springinaction/chapter01/knight/knight.xml");
Knight knight =
(Knight) ctx.getBean("knight");
1.2 配置的XML
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="greetingService"
class="com.springinaction.chapter01.hello.GreetingServiceImpl">
<property name="greeting"value="Buenos Dias!" />
</bean>
</beans>
1.3 创建Bean
1.3.1 声明一个简单Bean
<bean id="sonnet29"class="com.springinaction.springidol.Sonnet29"/>
<bean id="saxophone"class="com.springinaction.springidol.Saxophone"/>
1.3.2 通过构造函数注入
<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler">
<constructor-arg value="15"/> <!—注入数值 -->
<constructor-arg ref="sonnet29"/> <!—注入XML中声明的对象 -->
</bean>
Setter注入
<bean id="Saxophonist"
class="com.springinaction.springidol.Instrumentalist">
<property name="song"value="Jingle Bells" /> <!—注入简单数值à
<property name="instrument"ref="saxophone" /> <!—注入对象à
</bean>
1.3.3 注入内部Bean
特点:没有id属性
缺点:
1、 不能复用
2、 还会影响Spring上下文中XML的可读性
<bean id="Saxophonist"
class="com.springinaction.springidol.Instrumentalist">
<property name="song"value="Jingle Bells" />
<property name="instrument">
<bean class="com.springinaction.springidol.Saxophone"/>
</property>
</bean>
<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler">
<constructor-arg value="15"/> <!—注入数值 -->
<constructor-arg>
<bean class="com.springinaction.springidol.Sonnet29"/>
</constructor-arg/>
</bean>
1.3.4 装配集合
<list>、<set>:可与任意的java.util.Collection中的属性交换
<map>、<props>:props要求值、键都是String,map没有要求
<bean id="springIdol"class="com.springinaction.springidol.SpringIdol">
<property name="performers">
<list>
<ref bean="duke" />
<ref bean="kenny" />
<ref bean="hank" />
</list>
</property>
</bean>
<bean id="hank"class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<props>
<propkey="GUITAR">STRUM STRUM STRUM</prop>
<propkey="CYMBAL">CRASH CRASH CRASH</prop>
<propkey="HARMONICA">HUM HUM HUM</prop>
</props>
</property>
</bean>
<map>中的每个<entry>都有一个键和值组成
key(String),key-ref,value(String),value-ref
<bean id="hank"class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<map>
<entry key="GUITAR" value="STRUM STRUMSTRUM" />
<entry key-ref="instrument1"value-ref="saxophone"/>
</map>
</property>
</bean>
1.3.5 装配空值
<property name="someNonNullProperty"><null/></property>
1.3.6 自动装配(autowire)
byName,byType,constructor,autodetect
<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler"
autowire="constructor">
<!-- <constructor-arg ref="sonnet29"/> -->
</bean>
默认自动装配
在Spring配置文件的根元素<beans>中设置default autowire,就可以将所有的Bean设置为自动装配如:
<beans default-autowire="byName">
……
</bean>
缺点:不透明,不推荐使用
1.4 控制Bean创建
1.4.1 Bean范围化
每次请求时生成唯一的实例,设置scope属性
singleton,prototype,request,session,global-session
<bean id="saxophone"
class="com.springinaction.springidol.Saxophone"
scope="prototype" />
1.4.2 配置单例Bean
<bean id="theStage"
class="com.springinaction.springidol.Stage"
factory-method="getInstance" />
1.4.3 初始化和销毁Bean
在Bean中使用init-method和destroy-method属性
init-method=”初始化方法名” destroy-method=”销毁方法名”
默认初始化和销毁方法
在<beans>中使用
default-init-method=”初始化方法名”,
default-destroy-method=”销毁方法名”
还可以重写InitializingBean和DisposableBean接口,分别实现afterPropertiesSet(),destroy()方法,实现这些接口的缺点是应用Bean与SpringAPI相互耦合,建议用init-method和destroy-method
2 高级Bean装配
2.1 声明父Bean和子Bean
2.1.1 抽象基Bean类型
<bean id="baseSaxophonist"
class="com.springinaction.springidol.Instrumentalist"
abstract="true">
<property name="song"value="Jingle Bells" />
<property name="instrument"ref="saxophone" />
</bean>
继承
<bean id="kenny" parent="baseSaxophonist"/>
<bean id="david" parent="baseSaxophonist"/>
覆盖继承的属性
<bean id="frank"parent="baseSaxophonist">
<property name="song"value="Mary had a little lamb" />
</bean>
2.1.2 抽象共同属性
定义共同属性song,但它没有设置class属性
<bean id="basePerformer"abstract="true">
<property name="song"value="Somewhere Over the Rainbow" />
</bean>
子Bean利用自己的class属性来确定自己的类型
<bean id="taylor" class="com.springinaction.springidol.Vocalist"
parent="basePerformer"/>
<bean id="stevie"class="com.springinaction.springidol.Instrumentalist"
parent="basePerformer">
<property name="instrument"ref="guitar" />
</bean>
2.2 方法注入
方法替换
获取器注入
2.3 注入非SpringBean
2.0可以明确地配置在Spring之外实例化的Bean。也就是说,这些Bean不是由Spring创建的,但可以由Spring配置
@Configurable("pianist")
public class Instrumentalist implements Performer {
...
}
@Configurable的作用:
1、 表示Instrumentalist实例即使在Spring之外创建的,仍然可以由Spring进行配置
2、 它把Instrumentalist类与id为pianist的Bean关联起来。当Spring企图配置Instrumentalist实例时,会以pianist Bean作为模板
还需在Spring配置中添加如下内容:
<aop:spring-configured/>
2.4 注册自定义属性编辑器
2.5 使用Spring的特殊Bean
后处理Bean
Bean工厂的后处理
配置属性的外在化
提取文本消息
程序事件的解耦
让Bean了解容器
2.6 脚本化的Bean
3 通知Bean
3.1 AOP简介
Aspect Oriented Programming,面向切面编程,切面有助于实现交叉事务的模块化
3.1.1 术语
通知(Advice)
通知定义了切面是什么以及何时使用
切入点(Pointcut)
切入点定义了“何地”
切面(Aspect)
切面是通知和切入点的结合。通知和切入点共同定义了关于切面的全部内容—它的功能、在何时和何地完成其功能
连接点(Joinpoint)
引入(Introduction)
目标(Target)
代理(Proxy)
织入(Weaving)
3.1.2 Spring对AOP的支持
经典的基于代理的AOP(各版本Spring)
@AspectJ注解驱动的切面(仅Spring2.0)
纯POJO切面(仅2.0)
注入式AspectJ切面(各版本)
3.2 创建典型的切面
3.2.1 创建通知
5种形式
Before(前),After-returning(返回后),After-throwing(抛出后),Around(周围),Introduction(引入)
public class AudienceAdvice implements MethodBeforeAdvice,
AfterReturningAdvice, ThrowsAdvice {
public AudienceAdvice() {}
public void before(Method method, Object[] args, Object target)
throws Throwable {
audience.takeSeats();
audience.turnOffCellPhones();
}
//前通知,第一个参数是个java.lang.reflect.Method对象,它代表要使用这个通知的方法。第二个参数是一个Objects数组,是方法被调用时要传递的参数。最后一个参数是方法调用的目标。
public void afterReturning(Object rtn, Method method,
Object[] args, Object target) throws Throwable {
audience.applaud();
}
//rtn表示从被调用方法返回的值
public voidafterThrowing(Method method, Object[] args, Object target,
Throwable throwable) {
audience.demandRefund();
}
//最后一个参数必须,其他可选
//injected
private Audience audience;
public void setAudience(Audience audience) {
this.audience = audience;
}
}
定义Bean
<bean id="audience"class="spring.simple.springidol.Audience" />
<bean id="audienceAdvice"
class="spring.simple.springidol.AudienceAdvice">
<property name="audience"ref="audience" />
</bean>
3.2.2 周围通知
由MethodInterceptor接口来定义
public class AudienceAroundAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
audience.takeSeats();
audience.turnOffCellPhones(); //调用前
Object returnValue =invocation.proceed(); //调用目标方法
audience.applaud(); //成功返回之后
return returnValue;
} catch (PerformanceException throwable) {
audience.demandRefund(); //在出现异常之后执行
throw throwable;
}
}
//injected
private Audience audience;
public void setAudience(Audience audience) {
this.audience = audience;
}
}
好处:一是能以简洁的方式在一个方法里定义前通知和后通知。如果需要在执行方法之前和之后都使用通知,使用周围通知会比分别单独实现两种通知更方便。利用周围通知还可以检查和修改被通知方法的返回值
必须要调用proceed()方法
3.3 定义切点和通知者
3.3.1 正则表达式切点
<bean id="audiencePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern"value=".*perform" />
</bean>
Pattern属性用于指定方法匹配所使用的切点模板,本例中被设置为一个正则表达式,匹配任何类里名为perform()的方法
定义通知:
<bean id="audienceAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice"ref="audienceAdvice" />
<property name="pointcut"ref="audiencePointcut" />
</bean>
联合切点与通知者
RegexpMethodPointcutAdvisor是个特殊的通知者类,可以在一个Bean里定义切点和通知者
<bean id="audienceAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice"ref="audienceAdvice" />
<property name="pattern"value=".*perform" />
</bean>
3.3.2 AspectJ表达式切点
<bean id="audiencePointcut"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression"value="execution(* *.perform(..))" />
</bean>
execution(* *.perform(..)):
执行方法时(使用任意返回类型 任意类.perform()方法(任意参数))
要使用的通知类是AspectJExpressionPointcutAdvisor
<bean id="audienceAdvisor"
class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="advice"ref="audienceAdvice" />
<property name="expression"value="execution(* *.perform(..))" />
</bean>
通知者把通知与切点关联起来,从而完整地定义一个切面,但切面在Spring里是以代理的方式实现的。
3.4 使用ProxyFactoryBean
<bean id="bo"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="boTarget" /> //被通知的Bean
<property name="proxyInterfaces"
value="com.springinaction.springidol.Performer"/> //应该实现的哪个接口
<property name="interceptorNames"value="audienceAdvisor" />//通知者
</bean>
3.4.1 抽象ProxyFactoryBean
<bean id="audienceProxyBase"
class="org.springframework.aop.framework.ProxyFactoryBean"
abstract=”true”>
<property name="proxyInterfaces"
value="com.springinaction.springidol.Performer"/> <property name="interceptorNames" value="audienceAdvisor" />
</bean>
利用audienceProxyBase进行扩展
<bean id="stevie"parent="audienceProxyBase">
<property name="target" ref="stevieTarget" />
</bean>
<bean id="duke"parent="audienceProxyBase">
<property name="target" ref="dukeTarget" />
</bean>
3.5 自动代理
3.5.1 为Spring切面创建自动代理
在Spring上下文里声明如下的<bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
对于简单的通知或运行于java5之前的环境时,以上自动代理是不错的
3.5.2 自动代理@AspectJ切面
@Aspect //声明切面
public class Audience{
public Audience() {}
@Pointcut("execution(**.perform(..))") //定义演出切点
Public void performance(){}
@Before("performance()") //定义之前执行
public void takeSeats() {
System.out.println("The audience is taking their seats.");
}
@Before("performance()") //定义之前执行
public void turnOffCellPhones() {
System.out.println("The audience is turning off their cellphones");
}
@AfterReturning("performance()") //定义之后执行
public void applaud() {
System.out.println("CLAP CLAP CLAP CLAP CLAP");
}
@AfterThrowing("performance()") //定义出错执行
public void demandRefund() {
System.out.println("Boo! We want our money back!");
}
}
把以上Audience应用为一个切面还须在Spring上下文里声明一个自动代理Bean,它知道如何把@AspectJ注解的Bean转化为代理通知
自动代理创建器类:AnnotationAwareAspectJAutoProxyCreator,也可以用aop命名空间<aop:aspectj-autoproxy>
注解周围通知
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp) {
System.out.println("The audience is taking their seats.");
System.out.println("The audience is turning off their cellphones");
try {
jp.proceed();
System.out.println("CLAP CLAP CLAP CLAP CLAP");
} catch (Throwable throwable) {
System.out.println("Boo! We want our money back!");
}
}
3.6 利用AOP定义切面
<aop:config>
<aop:pointcut
id="performance"
expression="execution(* *.perform(..))" /> <!-- 定义切点 -->
<aop:aspect ref="audience">
<aop:before
method="takeSeats"
pointcut-ref="performance" />
<aop:before
method="turnOffCellPhones"
pointcut-ref="performance" />
<aop:after-returning
method="applaud"
pointcut-ref="performance" />
<aop:after-throwing
method="demandRefund"
pointcut-ref="performance" />
<aop:around
method="aroundAdvice"
pointcut-ref="performance"/>
</aop:aspect>
</aop:config>
3.7 注入AspectJ切面
(这部分在学习的时候也未搞清楚,示例代码是.aj的文件,还望高人指点)
package com.springinaction.springidol;
public aspect JudgeAspect {
public JudgeAspect() {}
pointcut performance() : execution(*perform(..));
after() returning() : performance() {
System.out.println(criticismEngine.getCriticism());
}
//injected
private CriticismEngine criticismEngine;
public void setCriticismEngine(CriticismEngine criticismEngine) {
this.criticismEngine = criticismEngine;
}
}
<bean id="criticismEngine"
class="com.springinaction.springidol.CriticismEngineImpl">
<property name="criticismPool">
<list>
<value>I'm not being rude, but that was appalling.</value>
<value>You may be the least talented person in thisshow.</value>
<value>Do everyone a favor and keep your day job.</value>
</list>
</property>
</bean>
<bean class="com.springinaction.springidol.JudgeAspect"
factory-method="aspectOf">
<property name="criticismEngine"ref="criticismEngine" />
</bean>
- Spring2学习笔记(1)
- Spring2.5学习笔记
- Spring2.5 学习笔记
- Spring2.5学习笔记
- spring2.5-reference学习笔记
- spring2.5 jdbcTemplate学习笔记
- Spring2.5学习笔记 [壹]
- Spring2.5学习笔记 [贰]
- Spring2.5学习笔记 [叁]
- 跟踪学习Spring2.5笔记 -1- 第一个Spring程序
- Spring2提供的Remote包学习笔记
- Spring2学习笔记(2)-使用数据库
- spring2.5.6学习笔记一:spring简介
- 学习笔记-----------------struts2 hibernate3 spring2.5整合
- Spring2.5注解(标注)学习笔记
- Spring2.0 AOP学习案例笔记
- Spring2.5注解(标注)学习笔记
- spring学习笔记13--Spring2.x+Hibernate3.x +Struts1.x整合开发(1)sh先行组合
- Oracle 操作函数
- JPA是什么
- 我的七个建议
- JavaScript实现类似Excel功能
- Ubuntu flash 乱码 (显示为方块) 解决方法
- Spring2学习笔记(1)
- vs2008 水晶报表部署后安装报错
- 高效时间管理-介绍GTD
- Android 倒影实现算法
- firefox实用插件
- 有用的代码
- Fedora中安装 OpenOffice 的 PPT Viewer
- 网页加载不同样式的实现方法
- CLRS (Introduction to Algorithms 2nd) reanding notes 3