spring学习(二)AOP面向切面编程

AOP的概述:

AOP Aspect Oriented Programing 面向切面编程  ------- Aspect 切面   

Spring AOP:在运行期间为目标对象创建代理对象,并织入增强代码!

AspectJ : Spring本身AOP 编写非常麻烦,整合AspectJ 简化 AOP开发  (重点掌握)

AOP相关术语:

JoinPoint(连接点):所谓连接点就是spring中被拦截到的点(方法),这些点指的就是方法,因为在spring中只支持方法类型的拦截;

PointCut(切入点):意思是要对哪些JointPoint进行拦截;

Advice(通知/增强):拦截到方法后需要织如的增强代码,其中包括 前置增强,后置增强,环绕增强,异常增强,最终增强;

Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

Target(目标对象):需要代理的目标对象;

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程. spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入 

Proxy(代理):一个类被aop增强后就产生了一个结果代理类

Aspect(切面):= PointCut(切入点) + Advice(通知) ;

代理模式:

为真是的业务对象创建代理对象,通过访问代理对象的方法,间接访目标对象,代理对象控制其目标对象的访问;

代理分为两种 : 静态代理 和 动态代理  ------------ 在实际开发中 静态代理使用很少 ,主要动态代理 

1) ,JDK提供的动态代理

* 前提: 必须代理对象要实现接口,返回代理对象,一定转换接口类型 
// 不想拦截 
return method.invoke(userService, args);

// 想拦截 
if(method.getName().equals(方法名)){
   // 拦截代码
}

*********  必须针对接口代理 ,没接口不能用jdk代理

2),CGLIB动态代理

* 优点:可以对具体类生成代理 ,不需要接口 
* 如果之前版本Spring 需要手动导入 cglib  
* Spring3.2 在 core包 整合cglib 开发包 

第一步: Enhancer 创建
第二步: enhancer.setSuperClass(Class) ; 根据类型生成代理 (可以是具体类型)
第三步: enhancer.setCallback(new MethodInterceptor(){}) 
****  MethodInterceptor 相当于 InvocationHandler。0么****  实现intercept 相当于 invoke  

不想拦截
return method.invoke(真实业务对象, args);

想拦截
if(method.getName().equals("xxxx")){
    拦截代码 
}



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Spring 传统AOP编程及概念

Spring 提供5种 Advice :
1) org.springframework.aop.MethodBeforeAdvice  目标方法执行前增强
2) org.springframework.aop.AfterReturningAdvice 目标方法执行后增强
3) org.aopalliance.intercept.MethodInterceptor  在方法之前后 分别增强
4) org.springframework.aop.ThrowsAdvice  在方法抛出异常增强
5) org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性  (不重要)

Spring 提供Advisor (传统Spring 提供切面) 
* Aspect 和 Advisor  区别 Aspect 指可以有多个PointCut和多个Advice    Advisor 指只能有一个PointCut 和 一个Advice 

1) Advisor : Advice 本身就是一个切面,拦截目标类所有方法
2) PointcutAdvisor  : 拦截PointCut 指定的方法 

使用Spring AOP 必须导入 AOP相关jar  (传统AOP)
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar (aop联盟jar)


Spring的applicationContext配置AOP内容:

1,通过 ProxyFactoryBean  为目标对象生成代理,织入 定义Advice

ProxyFactoryBean 常见属性 

1) proxyInterfaces  根据目标接口生成代理
2) interceptorNames  织入Advice
3) target 目标bean 
4) optimize 设置true 强制使用CGlib 生成代理 
5) proxyTargetClass  设置true  为目标类生成代理,而不是接口

案例一:通过一个Advice 作为一个切面 ,对目标类的所有方法进行拦截

	<!-- 为目标对象生成代理对象  -->
		<!-- 并没有配置 Advisor, 一个Advice 就是 Advisor , 对目标类 所有方法进行拦截 -->
		<bean id="userServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 代理接口 -->
		<!-- <property name="proxyInterfaces" value="cn.itcast.service.UserService"></property> -->
			<!-- 增强Advice -->
			<property name="interceptorNames" value="myMethodBeforeAdvice"></property>
			<!-- 配置拦截目标  -->
			<property name="target" ref="userService"></property>
		
			<!-- 如果为目标类生成代理 -->
	<!-- 		<property name="proxyTargetClass" value="true"></property> -->
		</bean>
案例二:定义切点,只拦截需要控制方法 

RegexpMethodPointcutAdvisor  正则表达式 切点切面   

	<!-- 配置环绕增强 -->
	<bean id="myMethodInterceptor" class="cn.itcast.advice.MyMethodInterceptor"></bean>
	
	<!-- 定义带有切点的切面  -->
	<bean id="regexAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<!-- 将Advice 配置 Advisor中 -->
		<property name="advice" ref="myMethodInterceptor"></property>
		<!-- 向patterns参数 传入正则表达式 -->
		<property name="patterns" value=".*search.*,.*save.*"></property>
	</bean>
	
	<!-- 生成代理对象 -->
	<bean id="userServiceProxy3" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces" value="cn.itcast.service.UserService"></property>
		<property name="interceptorNames" value="regexAdvisor"></property>
		<property name="target" ref="userService"></property>
	</bean>


**********************
自动代理
BeanNameAutoProxyCreator 根据Bean名称创建代理 (针对Bean所有方法) ---- 例如 100Service,只需要配置一次,为所有Bean方法生成代理 
DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理 (针对特定的方法)  --------- 非常重要 
**********************




----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二,AspectJ实现AOP(注解配置)

       1,导入jar包  Spring核心4个 日志2个 AOP2个 Aspecj2个

       2,配置applicationContext.xml导入aop名称空间

           <aop:aspectj-autoproxy />

      3,@AspectJ注解提供Advice类型

           @Before 前置通知,相当于BeforeAdvice
           @AfterReturning 后置通知,相当于AfterReturningAdvice
          @Around 环绕通知,相当于MethodInterceptor
          @AfterThrowing抛出通知,相当于ThrowAdvice
          @After 最终final通知,不管是否异常,该通知都会执行
         @DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

     4、切点定义
          通过execution 函数定义切入点
         语法 : execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

         execution(* *(..)) ---- 匹配所有方法
         execution(* cn.itcast.service..*(..)) 不包含子包
         execution(* cn.itcast.service.UserService.*(..)) 匹配UserService类所有方法

      5,例子,定义一个前置通知:

@Aspect
public class ProductAspect {
	@Before(value="execution(* cn.itcast.service.ProductService.*(..))")
	public void before(){
		System.out.println("前置通知....");
	}
}


       applicationContext.xml配置:

		<aop:aspectj-autoproxy />
		
		<!-- 配置目标bean -->
		<bean id="productService" class="cn.itcast.service.ProductServiceImpl"></bean>
		<bean id="userService" class="cn.itcast.service.UserServiceImpl"></bean>
		
		<!-- 配置切面 -->
		<bean id="productAspect" class="cn.itcast.aspect.ProductAspect"/>

 

        在通知方法传入参数 JoinPoint , 通过JoinPoint 获得当前拦截目标信息

        @Before前置通知 : @Before(value="execution(* cn.itcast.service.*Service.*(..))")
        @AfterReturning 后置通知 : @AfterReturning(value="execution(* cn.itcast.service.*Service.*(..))",returning="returnValue")
                         public void afterReturning(JoinPoint joinPoint, Object returnValue){ }

        @Around 环绕通知: 传入参数 ProccedingJoinPoint 控制目标方法执行  proceedingJoinPoint.proceed();

        @AfterThrowing 异常通知: 发生异常后,通知方法执行
        @After 最终通知 : 无论是否发生异常,目标方法都会执行

        struts2 提供大量 interceptors 使用AOP 思想

 

 


 



























      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值