AOP的自动代理

Spring的aop机制提供两类方式实现类代理。一种是单个代理,一种是自动代理。

单个代理通过ProxyFactoryBean来实现(就如上面的配置)。

自动代理:自动代理能够让切面定义来决定那个bean需要代理,不需要我们为特定的bean明确的创建代理从而提供一个更完整的aop实现 通过BeanNameAutoProxyCreator或者 DefaultAdvisorAutoProxyCreator实现。

◆采用单个代理方式 (费时费力,配置复杂臃肿)

下面就采用自动代理

实现代理bean的两种方式:

1,“基于Spring上下文的里声明的通知者bean的基本自动代理”:通知者的切点表达式用于决定哪个bean和那些方法需要被代理

2,”基于@AspectJ注释驱动切面的自动代理”:切面里包含的通知里指定的切点将用于选择哪个bean和哪个方法要被代理

第一种:<!——自动代理增加此行,容器会自动根据通知要匹配的切入点,为包含切入点的类创建 代理。注意这个bean没有id,因为永远都不会直接引用它——>

feedom.net   

第二种 自动代理@AspectJ切面

然而aspectJ提供可一种基于jdk1.5注解技术的方式,使得配置文件更少,更方便。能够把POJO类注释为切面这通常称为

@AspectJ.我们利用@AspectJ注释,我们不需要声明任何额外的类或Bean就可以把POJO转换成一个切面例如:

@Aspect 定义切面不再是普通的POJO了 在POJO类中加注释


public class AspectJMixAspect {    

    private Log logger = LogFactory.getLog(AspectJMixAspect.class);    

    @Pointcut("execution(* *..HelloIF.*(..)) || execution(* *..TestBeanIF.*(..))")定义切入点那些类的那些方法添加

    public void allMethods() {    }    

    @Pointcut("execution(* *..TestBeanIF.toDate(..)) && args(dateStr)")    

    public void toDate(String dateStr) {    

    }    

    @Around("allMethods()")    环绕通知

    public Object timing(ProceedingJoinPoint pjp) throws Throwable {    

        long begin = System.currentTimeMillis();    

        Object ret = pjp.proceed();    

        long end = System.currentTimeMillis();    

        String methodName = pjp.getSignature().getName();    

        String targetClass = pjp.getTarget().getClass().getName();    

        logger.info("Around advice: It took " + (end - begin) + "ms to call "

                        + methodName + " on " + targetClass);

        return ret;

    }

    @Before("allMethods()")

    public void logBefore(JoinPoint jp) {

        logger.info("Before advice: " + jp.getSignature().toLongString());    

    }    

    @AfterReturning(value="toDate(dateStr)", returning = "date", argNames = "date, dateStr")    

    public void afterReturning(Date date, String dateStr) {

        logger.info("call method toDate(" + dateStr + ") and return " + date);    

    }    

    @AfterThrowing(value="toDate(dateStr)", throwing="ex", argNames="dateStr, ex")    

    public void afterThrowing(String dateStr, ParseException ex){方法名任意但参数要和argNames=""中的参数顺序一样,

    }

}

配置文件


<?xml version="1.0" encoding="UTF-8"?>

<p:beans xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:p="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.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">

    <!-- target -->

    <p:bean id="hello" class="com.kettas.spring.ioc.day1.HelloIFImpl">

        <p:property name="cal">

            <p:bean class="java.util.GregorianCalendar"></p:bean>

        </p:property>

        <p:property name="user" value="world"></p:property>

    </p:bean>

    <p:bean id="testBean" class="com.kettas.spring.aop.day5.TestBean">

        <p:property name="pattern" value="yyyy-MM-dd"></p:property>

    </p:bean>

    <!-- apsect bean -->

    <p:bean id="aspectJAspect" class="com.kettas.spring.aop.day5.AspectJMixAspect"></p:bean>

<aop:aspectj-autoproxy></aop:aspectj-autoproxy> 声明自动代理bean需要命名空间:aop="http://www.springframework.org/schema/aop"

</p:beans>
原文地址:https://www.cnblogs.com/yuyu666/p/9795641.html