Spring AOP笔记

最近研究了下spring的aop,从spring2开始,spring支持基于XML和annotation的两种配置,先来看看基于XML配置的实现。

 

基于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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="log" class="com.inter.GetLog"></bean>

    <!--
        注意这里:expression="execution(* com.inter.*.print*(..))"
        括号里面第一个*号代表返回值 接下来  com.inter.*. 是你要切入的代码的大概路径,这里为什么用大概路径来形容呢
        因为这里的意思是符合以com.inter的路径都会作为选择的对象,也不详细介绍,查下就明白了, print*(..)是指
        方法名以print开头的都符合,括号里面的 .. 表示参数是随意的都可以。
    -->
    <aop:config>
        <aop:aspect ref="log">
            <aop:pointcut id="printMethods" expression="execution(* com.inter.*.print*(..))"/>
            <aop:around method="getLog" pointcut-ref="printMethods"/>
        </aop:aspect>
    </aop:config>
   
    <aop:config>
        <aop:aspect ref="log">
            <aop:pointcut id="dealException" expression="execution(* com.inter.*.excep*(..))"/>
            <aop:around method="getLog" pointcut-ref="dealException"/>
        </aop:aspect>
    </aop:config>

 

    <aop:config>
        <aop:aspect ref="log">
            <aop:pointcut id="before" expression="execution(* com.inter.*.bef*(..))"/>
            <aop:before method="before" pointcut-ref="before"/>
        </aop:aspect>
    </aop:config>   


    <!--要织入代码的bean-->
    <bean id="print" class="com.inter.SystemPrint"></bean>
   
</beans>

 

SystemPrin的实现类:

public class SystemPrint implements Print{
   
    public String print(String name){
        String result="hello " + name;
        System.out.println(result);
        return result;
    }

 

    public String before(String name){
        String result="before " + name;
        System.out.println(result);
        return result;
    }   

 

    public void exception(String name) throws Exception{
        System.out.println(name);
        throw new Exception();
    }
}

 

下面是所要织入的代码,也就是我们要用来打印和处理异常:

import org.aspectj.lang.ProceedingJoinPoint;
public class GetLog {   
    public void getLog(ProceedingJoinPoint joinpoint) throws Throwable {       
        System.out.println("===begin===");
        try{
            joinpoint.proceed();
        }
        catch(Exception e)
        {
            System.out.println("log exception!");
        }
        System.out.println("===end=====");
    }

 

   public void before(JoinPoint joint) throws Throwable
    {
        System.out.println("===begin===");
        System.out.println("before!");
    }

 

}

 

编写一个测试类,分别测试上面两个方法,可以得到如下的结果:

===begin===
hello ding
===end=====
-----------------
===begin===
laoding
log exception!
===end=====
-----------------
===begin===
before!
before beforeing

 

下面来看看基于Annotation的实现:

<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <!--基于@AspectJ切面的驱动器,如果没有这句话  切面的代码是不会执行的,可以试下-->
    <aop:aspectj-autoproxy/>


    <bean id="myAspect" class="com.inter.MyAspect"></bean>
    <bean id="hello" class="com.inter.HelloImpl"></bean>
   
</beans>

 

HelloImpl类的实现:

public class HelloImpl implements Hello {   
    public String hello(String name)
    {
        String say = "Hello," + name;

        System.out.println(say);
        return say;
    }
}

 

切面的实现:

//首先这是注释这个类就是切面
@Aspect
public class MyAspect {
    /*这里是注释要切入的方法,AfterReturning是表示方法返回以后进行切入,我这里
       选这个的话是因为日志一般都是在方法执行完成后记录,当然你可以拿Before来试*/
    @Around("execution(* com.inter.*.hello(..))")
    public void doLog(ProceedingJoinPoint joinpoint) throws Throwable{
        String result = (String)joinpoint.proceed();
        System.out.println("---doLog"+result);
    }
}

 

然后编写一个测试类,得到如下测试结果:

-----------------
Hello,xiao
---doLogHello,xiao

好的,关于Spring AOP笔记和源码讲解,我可以给你简单介绍一下。 Spring AOPSpring框架中的一个重要模块,提供了基于代理的AOP实现。AOP(Aspect Oriented Programming)面向切面编程,是一种编程思想,它通过将横切关注点与业务逻辑分离,使得系统的关注点更加清晰,代码更加简洁易懂,同时也提高了代码的可维护性和可扩展性。 在Spring AOP中,切面(Aspect)是一个类,它包含了通知(Advice)和切点(Pointcut)。通知是在切点上执行的操作,例如在方法执行前或执行后执行一些额外的逻辑。而切点则是一个表达式,用于匹配目标对象中的方法,从而确定哪些方法会被通知所影响。 Spring AOP提供了四种通知类型,分别是: 1. 前置通知(Before advice):在目标方法执行之前执行。 2. 后置通知(After returning advice):在目标方法执行之后执行,在目标方法没有抛出异常的情况下。 3. 异常通知(After throwing advice):在目标方法抛出异常后执行。 4. 最终通知(After advice):无论目标方法是否抛出异常,最终通知都会执行。 除了通知之外,Spring AOP还提供了环绕通知(Around advice),它可以在目标方法执行前和执行后执行一些额外的逻辑,并且可以控制目标方法的执行。 在Spring AOP中,代理是通过JDK动态代理或者CGLIB字节码生成技术生成的。如果目标对象实现了接口,则使用JDK动态代理实现代理;如果目标对象没有实现接口,则使用CGLIB字节码生成技术实现代理。 在Spring AOP中,通知和切点都可以使用注解的方式来声明。例如,使用@Aspect注解声明一个切面类,使用@Before、@After、@AfterReturning、@AfterThrowing和@Around注解声明通知方法,使用@Pointcut注解声明切点表达式。 关于Spring AOP源码讲解,它的实现主要涉及到以下几个类: 1. AdvisedSupport类:封装了目标对象、切面和通知等信息。 2. ProxyFactory类:用于生成代理对象的工厂类。 3. AopProxy接口:代理对象的接口。 4. JdkDynamicAopProxy和CglibAopProxy类:实现了AopProxy接口,分别用于基于JDK动态代理和CGLIB字节码生成技术的代理对象。 以上是Spring AOP笔记和简单源码讲解,希望能对你有所帮助。如果有什么不清楚的地方,可以继续问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值