Spring经典总结(四)

2014-11-24 08:27:12 · 作者: · 浏览: 6
示例2:匹配CostServiceImpl类中所有方法
execution(* tarena.service.CostServiceImpl.*(..))
示例3:匹配tarena.service包下所有类的所有方法
execution(* tarena.service.*.*(..))
示例4:匹配tarena.service包及其子包下所有类所有方法
execution(* tarena.service..*.*(..))
示例5:匹配容器Bean对象中的find开始的方法,并且是 public void 修饰的
execution(public void find*(..))
*(2).类型限定表达式
可以规定哪个类中的所有方法被切入方面组件
格式:within(包名.类型名)
示例1:匹配CostServiceImpl类中所有方法
within(tarena.service.CostServiceImpl)
示例2:匹配tarena.service包下所有类所有方法
within(tarena.service.*)
示例3:匹配tarena.service包及其子包中所有类所有方法
within(tarena.service..*)
(3).Bean的Id或Name名称限定
可以按定义时,id或name属性值匹配
bean(beanIdOrName)
示例1:匹配容器中id=costService的Bean对象
bean(costService)
示例2:匹配容器中id值以Service结尾的对象
bean(*Service)
(4).参数类型限定
args(参数类型列表)
示例1:匹配有且只有一个参数,参数类型符合
Serializable类型的方法
args(java.io.Serializable)
*注意:上述切入点表达式可以联合使用,采用&&,||连接
3)连接点(JoinPoint)
// 连接点的集合组成切入点,连接点指的是切面组件在目标对象上 // 作用的位置,例如:在方法调用前、方法调用后、或者发生异常。
切入点是连接点的集合。代表方面组件和某一个目标方法的关联点。
*4)通知(Advice)
用于指定方面组件作用于目标对象中的目标方法的时机。例如前置
通知,意思是先执行方面组件,再执行目标方法。
Spring提供了5种类型的通知。用于指定方面组件在目标方法哪个
位置切入。Spring经典总结
a.前置通知
先执行方面组件,再执行目标组件方法
b.后置通知
先执行目标组件方法,没有异常再执行方面组件。
如果发生异常,不会执行方面组件
c.异常通知
当目标方法抛出异常之后,执行方面组件。
d.最终通知
先执行目标方法,无论有没有异常都执行方面组件
e.环绕通知
相当于前置+后置通知。在目标方法前和后都执行方面组件
内部实现原理:
try{
//前置通知切入
//环绕前置通知切入
//目标组件方法
//环绕后置通知切入
//后置通知切入
}catch(){
//异常通知切入
}finally{
//最终通知切入
}
5)目标对象(Target)
方面组件作用的对象,即与切入点表达式匹配的对象。
6)动态代理(AutoProxy)
Spring采用了动态代理技术实现了AOP控制。
如果Spring采用了AOP配置后,容器getBean方法返回的组件对象
是代理对象(一个动态生成类型,即动态代理类),用户在使用时,由
代理对象调用切面组件和目标对象的功能。
Spring采用的动态代理技术有以下两种:
a.目标对象没有接口(使用cglib.jar工具包)
适用于目标组件没有接口实现的情况。
public class $Service$$Enhancer$CGLIB extends
原目标组件类型{
//重写目标对象的方法,在重写的方法中调用目标对象和方面组 件对象功能
}
b.目标对象有接口(采用JDK Proxy API)
适用于目标组件有接口实现的情况。
public class $Proxy4 implements 原目标组件接口{
//重写目标接口方法,在重写的方法中调用目标对象和方面组件对
象功能
}
public void testDelete() {
String[] confs = { "applicationContext.xml" };
ApplicationContext ac = new ClassPathXmlApplicationContext(confs);
CostService service = (CostService) ac.getBean("costService");
System.out.println("类名:"+service.getClass().getName());
//获得代理类中的所有public方法
Method[] ms =service.getClass().getMethods();
for(Method m : ms){
System.out.println(m);
}
service.deleteCost();
}Spring经典总结
程序运行结果如下:
类名:$Proxy4
public final void $Proxy4.addCost()
public final void $Proxy4.d