AOP的实现方式

AOP(面向切面编程)是OOP的补充,用于解决系统层面问题。主要实现方式包括:1.基于Spring容器的自动代理;2.AspectJ技术结合Spring AOP配置;3.使用注解进行AOP编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP(Aspect Oriented Programming)
被称为面向切面编程,是OOP(面向对象编程的一种补充),主要用来解决一些系统层面上的问题
AOP的三种实现方式:
1.基于Spring容器的自动代理实现AOP:
 	<!--被代理对象-->
    <bean id="orderServiceTargetBean" class="com.apesource.service.impl.OrderServiceImpl"/>
    <bean id="userServiceTargetBean" class="com.apesource.service.impl.UserServiceImpl"/>

    <!--通知(Advice)-->
    <bean id="logAdviceBean" class="com.apesource.LogAdvice"/>
    <bean id="performanceAdviceBean" class="com.apesource.PerformanceAdvice"/>

    <!--切入点(Poinecut)-->
    <bean id="createPointcutBean" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value=".*create.*"/>
    </bean>

    <!--Advisor(高级通知) = Advice(通知) + Pointcut(切入点)-->
    <bean id="performanceAdvisorBean" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <!--注入通知-->
        <property name="advice" ref="performanceAdviceBean"/>

        <!--注入切入点-->
        <property name="pointcut" ref="createPointcutBean"/>
    </bean>

<!--自动代理对象-->
    <bean 				class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

        <!--被代理对象(目标对象)列表:根据Bean名称规则指定那些bean创建自动代理-->
        <property name="beanNames">
            <list>
                <value>*TargetBean</value>
            </list>
        </property>

        <!--通知列表-->
        <property name="interceptorNames">
            <list>
                <value>logAdviceBean</value>
                <value>performanceAdvisorBean</value>
            </list>
        </property>
    </bean>
2.AspectJ技术,通过切面Aspect,基于Spring AOP的配置实现AOP:
 
 	/**
     * 前置通知
     */
    @Before(EXPRESSION)
    public void beforeAdvice(JoinPoint joinPoint){
        System.out.println("=========【使用AspectJ实现前置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("=========【使用AspectJ实现前置通知】结束=========");
    }

    /**
     * 后置通知(有返回值)
     * @param joinPoint
     * @param returnValue:返回值
     * @return:目标方法的返回值
     */
    public Object afterReturningAdvice(JoinPoint joinPoint, Object returnValue){
        System.out.println("=========【使用AspectJ实现后置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("返回值:" + returnValue);
        System.out.println("=========【使用AspectJ实现后置通知】结束=========");
        return returnValue;
    }

    /**
     * 后置通知(无返回值)
     * @param joinPoint
     */
    public void afterAdvice(JoinPoint joinPoint){
        System.out.println("=========【使用AspectJ实现后置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("=========【使用AspectJ实现后置通知】结束=========");
    }

    /**
     * 异常通知
     * @param joinPoint
     * @param ex:异常对象
     */
    public void throwingAdvice(JoinPoint joinPoint, Exception ex){
        System.out.println("=========【使用AspectJ实现异常通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("出现异常:" + ex.getMessage());
        System.out.println("=========【使用AspectJ实现异常通知】结束=========");
    }

    /**
     * 环绕通知
     * @param joinPoint
     * @return:目标方法的返回值
     * @throws Throwable
     */
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("=========######【使用AspectJ实现环绕通知】######开始=========");
        Object returnValue = joinPoint.proceed();
        System.out.println("=========######【使用AspectJ实现环绕通知】######结束=========");
        return returnValue;
    }


	<!--被代理对象(目标对象)bean-->
    <bean id="orderServiceBean" class="com.apesource.service.impl.OrderServiceImpl"/>
    <bean id="userServiceBean" class="com.apesource.service.impl.UserServiceImpl"/>

    <!--日志Aspect切面bean-->
    <bean id="logAspectBean" class="com.apesource.aspect.LogAspect"/>

    <!--使用Aspect实现切面,使用Spring AOP进行配置-->
    <aop:config>
        <!--配置切面-->
        <!--注入切面bean-->
        <aop:aspect ref="logAspectBean">

            <!--定义Pointcut:通过expression表达式,来查找特定的方法(pointcut)-->
            <aop:pointcut id="serviceMethodPointuct" expression="execution(* com.apesource.service.impl.*.create*(..) )"/>

            <!--配置“前置通知”-->
            <!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“前”,执行当前logAspectBean的beforeAdvice前置通知方法-->
            <aop:before method="beforeAdvice" pointcut-ref="serviceMethodPointuct"/>

            <!--配置“后置通知”(有返回值)-->
            <!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“后”,执行当前logAspectBean的afterReturningAdvice后置通知方法-->
            <aop:after-returning returning="returnValue" method="afterReturningAdvice" pointcut-ref="serviceMethodPointuct"/>

            <!--配置“后置通知”(无返回值)-->
            <!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“后”,执行当前logAspectBean的afterAdvice后置通知方法-->
            <aop:after method="afterAdvice" pointcut-ref="serviceMethodPointuct"/>

            <!--配置“异常通知”-->
            <!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行中出现异常时,执行当前logAspectBean的throwingAdvice异常通知方法-->
            <aop:after-throwing throwing="ex" method="throwingAdvice" pointcut-ref="serviceMethodPointuct"/>

            <!--配置“异常通知”(有返回值)-->
            <!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行前后,执行当前logAspectBean的aroundAdvice环绕通知方法(包括前置和后置)-->
            <aop:around method="aroundAdvice" pointcut-ref="serviceMethodPointuct"/>
        </aop:aspect>
    </aop:config>
</beans>
3.通过注解实现AOP:
 	<!--自动扫描器-->
    <context:component-scan base-package="com.apesource"/>

    <!--配置AspectJ的动态代理-->
    <aop:aspectj-autoproxy/>
</beans>

 	/**
     * 前置通知
     * @param joinPoint
     */
    @Before(EXPRESSION)
    public void beforeAdvice(JoinPoint joinPoint){
        System.out.println("=========【使用AspectJ实现前置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("=========【使用AspectJ实现前置通知】结束=========");
    }

    /**
     * 后置通知(有返回值)
     * @param joinPoint
     * @param returnValue:返回值
     * @return:目标方法的返回值
     */
    @AfterReturning(value = EXPRESSION,returning = "returnValue")
    public Object afterReturningAdvice(JoinPoint joinPoint, Object returnValue){
        System.out.println("=========【使用AspectJ实现后置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("返回值:" + returnValue);
        System.out.println("=========【使用AspectJ实现后置通知】结束=========");
        return returnValue;
    }

    /**
     * 后置通知(无返回值)
     * @param joinPoint
     */
    @After(EXPRESSION)
    public void afterAdvice(JoinPoint joinPoint){
        System.out.println("=========【使用AspectJ实现后置通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("参数列表:" + joinPoint.getArgs());
        System.out.println("=========【使用AspectJ实现后置通知】结束=========");
    }

    /**
     * 异常通知
     * @param joinPoint
     * @param ex:异常对象
     */
    @AfterThrowing(value = EXPRESSION,throwing = "ex")
    public void throwingAdvice(JoinPoint joinPoint, Exception ex){
        System.out.println("=========【使用AspectJ实现异常通知】开始=========");
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("目标方法:" + joinPoint.getSignature().getName());
        System.out.println("出现异常:" + ex.getMessage());
        System.out.println("=========【使用AspectJ实现异常通知】结束=========");
    }

    /**
     * 环绕通知
     * @param joinPoint
     * @return:目标方法的返回值
     * @throws Throwable
     */
    @Around(EXPRESSION)
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("=========######【使用AspectJ实现环绕通知】######开始=========");
        Object returnValue = joinPoint.proceed();
        System.out.println("=========######【使用AspectJ实现环绕通知】######结束=========");
        return returnValue;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值