SpringAOP原理

来源:互联网 发布:艾宾浩斯记忆曲线软件 编辑:程序博客网 时间:2024/06/05 14:48

-----------------------------------Spring AOP----------------------------------------

Spring AOP ,即面向切面编程。

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。

   前提条件:将需要aop的类加入ioc容器,将切面类加入ioc容器

     1). 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"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">    <!-- 将扫描com.spring.busi包以及子包下的 带有@Controller,@Component,@Service,@Repository 的bean,纳入ioc容器 -->  <context:component-scan base-package="com.spring.framework"></context:component-scan><!-- 开始spring动态代理 -->  <aop:aspectj-autoproxy></aop:aspectj-autoproxy>    <!-- spring aop xml配置方法 -->  <bean id="loggerAspect" class="com.spring.framework.Aop.LoggerAspect"></bean>  <aop:config>       <!-- 配置切点表达式 -->      <aop:pointcut expression="execution(public * com.spring.framework.Aop.CalculatorImpl.*(..))" id="pointcut"/>      <aop:aspect ref="loggerAspect">          <aop:before method="beforeMethod" pointcut="pointcut"/>      </aop:aspect>  </aop:config></beans>

    2).注解方式实现

package com.spring.framework.Aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;//将该类声明为一个切面: 需要把类放入ioc容器@Component ,再声明一个切面@Aspect@Component@Aspectpublic class LoggerAspect {@Pointcut("execution(public * com.spring.framework.Aop.CalculatorImpl.*(..))")public void pointcut(){}//声明该方法为前置通知:在目标方法之前执行@Before("pointcut()")public void beforeMethod(JoinPoint joinPoint){String methodName = joinPoint.getSignature().getName();System.out.println("methodName :"+methodName);System.out.println("beforeMethod ..");}//后置通知在目标方法执行后执行(无论是否发生异常,发生异常也会执行)@After("pointcut()")public void afterMethod(JoinPoint joinPoint){String methodName = joinPoint.getSignature().getName();System.out.println("methodName :"+methodName);System.out.println("afterMethod ..");}@AfterReturning(returning="result" , pointcut="pointcut()")public void afterReturning(JoinPoint joinPoint, Object result){String methodName = joinPoint.getSignature().getName();System.out.println("methodName :"+methodName +", result:"+result);}/** * 环绕通知需要携带参数ProceedingJoinPoint * @param pjp * @return */@Around("pointcut()")public Object AroundMethod(ProceedingJoinPoint pjd){Object result = null;String methodName = pjd.getSignature().getName();try {//前置通知System.out.println("Before--methodName :"+methodName +", param :"+ Arrays.asList(pjd.getArgs()));//执行目标方法result=pjd.proceed();//后置通知System.out.println("After--methodName :"+methodName +", result :"+ result);} catch (Throwable e) {e.printStackTrace();//异常通知System.out.println("Exception--methodName :"+methodName +", exception :"+ e);}//后置通知System.out.println("After--methodName :"+methodName +", ends ....");return result;}}


原创粉丝点击