`
wei5201
  • 浏览: 187277 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于一次aop的经验

阅读更多
公司最近要求在某些程序出异常的时候,发封邮件至某个coder,用来及时检查问题所在,要求详细知道哪个类,哪个方法出的异常,出的什么异常等,而且不修改以前的程序代码!

于是想到了spring的AOP.想到了其中的ThrowsAdvice接口,这是用来再程序出了异常之后拦截,而后添加功能的.

本以为很简单,于是简单些了下测试类,测试的业务类没有实现接口,就是一个java类,本身应用了spring的申明事务.步骤如下:

1.先写一个pojo的advice通知:
public class Advice  {
	 public void throwing(Exception ex){  
		      System.out.println("pojo的afterThrowing...exception:"+ex.getMessage());  
	 }  
}



2.spring配置文件,把通知应用到pointcut中:
<bean id="adviceBean" class="com.zhangwei.struts.Advice"></bean>  
    <!-- 利用spring AOP的配置元素定义一个通知 -->  
    <aop:config >    
    
        <!-- 引用刚才定义的一个纯粹的POJO切面Bean -->  
	    <aop:aspect ref="adviceBean">  
	        <!-- 定义一个命名切点,必点切点定义的重复,expression用于配置匹配规则,(返回类型 返回类.方法(参数设置) -->  
	        <aop:pointcut id="todo" expression="execution(* com.zhangwei.struts.Bo.*(..)) " />     
	        <!-- 方法跑出异常后通知 -->           
	        <aop:after-throwing pointcut-ref="todo" method="throwing"  throwing="ex"/>  
	    </aop:aspect>  
    </aop:config>    


之后运行,发现错了,原因在于我的测试业务类没有实现某一接口,因为事务管理用了AOP,我的advice又用了AOP,事务管理时我的业务类成了proxy,应用我的advice时,proxy无法类型转换至业务类,报错.后来又了解决方式,就是指定proxyTargetClass的值为true,强制使用cglib生成子类,代码如下:
<aop:config proxy-target-class="true">    
    
        <!-- 引用刚才定义的一个纯粹的POJO切面Bean -->  
	    <aop:aspect ref="adviceBean">  
	        <!-- 定义一个命名切点,必点切点定义的重复,expression用于配置匹配规则,(返回类型 返回类.方法(参数设置) -->  
	        <aop:pointcut id="todo" expression="execution(* com.zhangwei.struts.Bo.*(..)) " />     
	        <!-- 方法前通知 -->           
	        <aop:after-throwing pointcut-ref="todo" method="throwing"  throwing="ex"/>  
	    </aop:aspect>  
    </aop:config>      
    
    
	<bean id="txProxyTemplate" abstract="true"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="proxyTargetClass">
			<value>true</value>
		</property>
		<property name="transactionManager" ref="transactionManager" />
		<property name="transactionAttributes">
			<props>
				<prop key="save*">PROPAGATION_REQUIRED</prop>
				<prop key="remove*">PROPAGATION_REQUIRED</prop>
				<prop key="update*">PROPAGATION_REQUIRED</prop>
				<prop key="login*">PROPAGATION_REQUIRED</prop>
				<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
			</props>
		</property>
	</bean>


但是这样做的后果就是拦截器重复拦截,因为2个AOP功能,2个子类,同时起作用,就拦截了2次.解决方案:把我的业务类换成接口,方法调用改成接口调用.

本以为可以了,但是发现advice的method,target参数无法得到,配置如下:
  <aop:after-throwing pointcut-ref="todo" method="throwing"  throwing="ex"/> 

无法给通知传参,只能得到一个exception类型的参数,得不到method,target等参数,琢磨了2小时,没有解决,头昏脑胀!

休息一小时,继续琢磨,得到正确解决方式:
1.写一个依赖于spring的advice:
public class Advisor implements ThrowsAdvice {
	 public void afterThrowing(Method method, Object[] args, Object target,    
		      Exception ex) {   
		      System.out.println("传统经典aop的afterThrowing2...");  
		      System.out.println("methodName:"+method.getName());
		      System.out.println("traget:"+target.getClass().getInterfaces()[0].getName());
	 }   
}


2.重新写配置文件:
<!-- 定义一个依赖于spring的通知 -->  
    <bean id="advice" class="com.zhangwei.struts.Advisor"></bean>
    <aop:config >
        <!-- 定义AOP的切入点 -->    
        <aop:pointcut id="todo" expression="execution(* com.zhangwei.struts.Bo.*(..)) " />     
        <!-- 定义建议者,需要通知以及切入点2个元素 -->
        <aop:advisor advice-ref="advice" pointcut-ref="todo"/>
    </aop:config>     


解决问题!

************************************************************************************************

可是由于公司项目业务层是java类,又不能修改以前的代码,只能采用链式加AOP的方式去做了:
 <bean id="login" class="com.zhangwei.struts.BoLogin">   
        <property name="daoLogin">   
            <ref bean="daoLogin" />   
        </property>   
    </bean>   

<!-- 定义一个依赖于spring的通知 -->  

    <bean id="advice" class="com.zhangwei.struts.Advisor"></bean>   
    <bean id="memberAopAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">   
        <property name="mappedName" value="*" />   
        <property name="advice" ref="advice" />   
    </bean>   
       
   <!-- 第一层代理 -->
    <bean id="loginProxy" class="org.springframework.aop.framework.ProxyFactoryBean">   
    <!--启用CGLib,代理的不再是接口-->   
        <property name="proxyTargetClass">   
            <value>true</value>   
        </property>   
        <property name="target">   
            <ref bean="login"/>   
        </property>   
        <property name="interceptorNames">   
            <value>memberAopAdvisor</value>   
        </property>   
    </bean>   
      
        
    <!-- 第二层代理对第一层代理继续代理 -->    
    <bean id="boLogin"   
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
        <!--启用CGLib,代理的不再是接口-->  
	<property name="proxyTargetClass">      
            <value>true</value>      
        </property>    
        <property name="target">      
            <ref bean="loginProxy"/>      
        </property>  
        <property name="transactionManager" ref="transactionManager" />   
        <property name="transactionAttributes">   
            <props>   
                <prop key="save*">PROPAGATION_REQUIRED</prop>   
                <prop key="remove*">PROPAGATION_REQUIRED</prop>   
                <prop key="update*">PROPAGATION_REQUIRED</prop>   
                <prop key="login*">PROPAGATION_REQUIRED</prop>   
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>   
            </props>   
        </property>   
    </bean>   


程序中最后调用"boLogin"这个spring Bean 就没有问题了.
Ok!解决!
分享到:
评论

相关推荐

    Spring使用AOP的三个jar包

    Spring的AOP框架就是基于这些接口构建的,这样开发者可以编写一次拦截器,就可以在多个AOP框架中复用。 这三个jar包在Spring AOP中的角色如下: 1. `aspectjrt.jar`:提供AspectJ的运行时支持,用于实现基于...

    springAop与spring定时器

    在这个例子中,`MyAspect`类定义了一个切面,`logBefore`方法作为前置通知在执行`com.example.service`包下的所有方法前运行,`scheduledTask`方法是一个定时任务,每5秒执行一次。 通过结合Spring AOP和定时任务,...

    C++ AOP编程理论

    面向切面编程(Aspect-Oriented Programming,AOP)是一种编程范式,旨在将横切关注点(crosscutting concerns)从业务逻辑代码中分离出来,以提高模块化。C++中的AOP理论探讨了如何在C++平台上实现面向切面编程,...

    aop 权限验证demo

    在IT行业中,AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它旨在提高软件的可维护性和可复用性,通过将关注点分离来简化代码结构。权限验证是软件系统中一个重要的安全机制,用于确保只有具有...

    Spring之AOP介绍

    // 第一次调用 login.login(); // 第二次调用 login.login(); // 第三次调用 ``` 5. **配置文件**: ```xml &lt;bean id="advice" class="org.nitpro.aop.before.LoginBeforeAdvice" /&gt; ...

    spring AOP依赖三个jar包

    1. aopalliance-1.0.jar:这是一个非常基础的AOP库,定义了AOP的核心接口,如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,这些接口为不同的AOP框架提供了统一的交互方式。...

    AOP四种配置方式demo

    AOP通过定义切面(Aspect)、通知(Advice)、切入点(Pointcut)和织入(Weaving)等概念,使得我们可以编写一次代码,然后在多个位置应用,而无需在每个具体方法中重复这些通用逻辑。 AOP的四种配置方式主要包括...

    aop示例spring 的aop思想解决项目中多次出现的同一个问题

    AOP允许我们在不修改原有业务逻辑的情况下,将这些共性功能以一种模块化的方式插入到业务代码中,从而提高了代码的可复用性和可维护性。 首先,理解AOP的核心概念: 1. **切面(Aspect)**:切面是关注点的模块化,...

    aopalliance源码

    `MethodInvocation`接口则代表了对目标方法的一次调用,它包含了关于方法的信息,如方法名、参数等,以及调用的能力。通过实现这些接口,开发者可以创建自己的拦截器,实现在方法调用前后的扩展逻辑。 接下来,我们...

    spring_aop.rar

    这样,我们可以编写一次切面代码,然后在多个类或方法中重复使用,从而提高代码的可复用性和可维护性。 **1.2 AOP的相关术语** - **切面(Aspect)**:切面是关注点的模块化,它包含了通知和切点。 - **通知...

    一个简单aop分享.zip

    本次分享的"一个简单aop分享.zip"可能包含了一次关于如何在Spring框架中使用AOP进行编程的讲解。 首先,理解AOP的基本概念非常重要。切面(Aspect)是关注点的模块化,它封装了跨越多个对象的行为或责任。通知...

    java分页 动态代理 aop实现

    在处理大量数据时,一次性加载所有数据不仅会消耗大量的内存,也可能导致用户界面响应变慢。因此,分页技术应运而生。在Java中,实现分页通常有以下几种方式: 1. 手动分页:开发者自行编写SQL查询,通过LIMIT和...

    java文件上传,断点续传+aop操作日志

    当用户再次尝试上传或下载时,系统会检查这些元数据,并从上一次停止的位置开始。这个过程可能需要服务器端存储文件的部分内容,并能识别和合并不同的部分。 3. **AOP(面向切面编程)**: AOP是Java中一种用于...

    android 实现AOP 使用Aspectj Kotlin版Demo.zip

    FastClickAop通常通过AOP来实现,当用户连续点击时,确保按钮在一定时间内只能响应一次点击事件,防止重复操作。 使用AspectJ与Kotlin结合实现AOP,主要步骤如下: 1. 引入AspectJ库:在项目build.gradle文件中...

    Android-AOP实现无侵入提高开发效率工具

    通过AOP,我们可以把这些功能编写一次,然后在整个应用程序中跨多个对象和方法应用,而无需在每个具体的地方重复代码,从而实现了代码的解耦和模块化。 在Android中,我们可以使用第三方库如AspectJX或者Android ...

    java 实现AOP

     假设系统由一系列的BusinessObject所完成业务逻辑功能,系统要求在每一次业务逻辑处理时要做日志记录。这里我们略去具体的业务逻辑代码。 Java代码 public interface BusinessInterface {  public void ...

    spring boot AOP注解方式实现多数据源

    4. **AOP注解**:在AOP中,我们可以使用`@Aspect`注解定义一个切面,然后使用`@Before`、`@After`、`@Around`等通知来执行相应的操作。在这个场景下,我们可以在方法上添加自定义注解,比如`@UseDataSource("primary...

    spring-aop-4.2.6.RELEASE.zip

    本资料包"spring-aop-4.2.6.RELEASE.zip"正是针对Spring AOP的一个重要版本,它与"spring-framework.zip"一同构成了强大的弹簧框架体系。开源项目的精神在此得以充分体现,为开发者提供了丰富的功能和高度的灵活性。...

    .NET平台下的依赖注入(IOC)和 面向切面(AOP)相结合简洁实用的使用方式

    力求获得一种简洁实用的方法实现IOC和AOP相结合的使用方式。 查阅了多个技术资料。经过多次测试,基本达到目的。 IOC使用微软的 Microsoft.Practices.Unity,AOP 使用微软企业库的 Microsoft.Practices.Enterprise...

    第四章:Spring AOP API 设计模式1

    5. **单例模式(Singleton)**:Spring AOP中的`SingletonTargetSource`保证了每个目标对象只被创建一次,实现了单例模式,确保在整个应用程序中只有一个共享的实例存在,提高了资源利用效率。 6. **适配器模式...

Global site tag (gtag.js) - Google Analytics