Spring framework(十四)AspectJ

一、概念

AspectJ是一个基于java语言的AOP框架,扩展了java语言,提供了强大的AOP功能。

使用AspectJ需要jar包:Aspectjrt.jar、Aspectjweaver.jar、Aspectj.jar
下载地址:https://www.eclipse.org/aspectj/downloads.php

使用方式:

  • 基于XML声明式AspectJ
  • 基于Annotation的声明式AspectJ

二、基于AspectJ XML开发

所有的切面都需要定义在aop:config元素中:

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

</beans>

2.1、定义切面aop:aspect

该元素可以将定义好的Bean转换为切面Bean,所以使用aop:aspect需要定义一个普通的SpringBean。

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

    <bean id="test" class="com.jsonliu.bean.Test"/>
    <aop:config>
        <aop:aspect id="myAspect" ref="test">

        </aop:aspect>
    </aop:config>
</beans>

2.2、定义切入点aop:pointcut

aop:pointcut用来定义一个切入点,当aop:pointcut元素作为aop:config元素的子元素定义时,表示该切入点是全局切入点,它可以被多个切面共享;当aop:pointcut元素作为aop:aspect元素的子元素定义时,表示该切入点只对当前切面有效。

 <aop:config>
        <aop:pointcut id="myPointCut" expression="execution(* com.jsonliu.service.*.*(..))"/>
 </aop:config>

id表示切入点唯一标识名称,execution用于指定切入点关联的切入点关系。

2.3、excution表达式

execution(modifiers-pattern returning-type-pattern declaring-type-pattern name-pattern(param-pattern)throws-pattern)

return-type-pattern、name-pattern、param-pattern必须,其他可选。

注意:return-type-pattern、name-pattern表达式之前有空格

参数说明
modifiers-pattern修饰符:private、public
returning-type-pattern返回值类型,*表示可以为任何返回值,如果返回值为对象,则需要指定全路径类名。
declaring-type-pattern指定方法的包名。
name-pattern指定方法名,代表所,set代表以set开头的所有方法。
param-pattern指定方法的参数(声明的类型,(…)代表所有从那时速,(.)代表一个参数,(.,String)代表第一个参数为任何值,第二参数是String类型)
throws-pattern指定抛出的异常类型

2.4、实例

public class Logging {

    public void beforeAdvice(){
        System.out.println("前置通知");
    }

    public void afterAdvice(){
        System.out.println("后置通知");
    }

    public void afterReturningAdvice(Object retVal){
        System.out.println("返回值为:"+retVal.toString());
    }

    public void afterThrowingAdvice(IllegalArgumentException ex){
        System.out.println("异常信息:"+ex.toString());
    } 
}
public class Man {
    private String name;
    private Integer age;

    public Man() {
        System.out.println("Man的无参构造函数");
    }

    public Man(String name, Integer age) {
        System.out.println("Man的有参构造函数");
        this.name = name;
        this.age = age;
    }

    public void show(){
        System.out.println("名称:"+name+",年龄:"+age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void throwException(){
        System.out.println("Man抛出异常");
        throw new IllegalArgumentException();
    }
}
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <bean id="man" class="com.jsonliu.bean.Man">
        <property name="name" value="天下"/>
        <property name="age" value="1000" />
    </bean>

    <bean id="logging" class="com.jsonliu.aspect.Logging"/>

    <aop:config>
        <aop:aspect id="logs" ref="logging">
            <aop:pointcut id="selectAll" expression="execution(* com.jsonliu.bean.*.*(..))"/>
            <!--  前置通知  -->
             <aop:before pointcut-ref="selectAll"  method="beforeAdvice"/>
            <!--  后置通知  -->
            <aop:after-returning pointcut-ref="selectAll" method="afterReturningAdvice" returning="retVal"/>
            <!--  异常通知  -->
            <aop:after-throwing pointcut-ref="selectAll" method="afterThrowingAdvice" throwing="ex" />
            <!--  最终通知  -->
            <aop:after pointcut-ref="selectAll" method="afterAdvice" />

        </aop:aspect>
    </aop:config>
</beans>
public class TestAop {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("AspectBeans.xml");
        Man man = (Man) context.getBean("man");
        man.getName();
        man.getAge();
        man.throwException();
    }
}

执行结果:

在这里插入图片描述

三、基于AspectJ注解开发

3.1、概念

AspectJ框架为AOP开发提供了一套注解,允许使用注解定义切面、切入点和增强处理,Spring框架可以根据这些注解生成AOP代理。

名称说明
@Aspect用于定义一个切面
@Pointcut用于定义一个切入点
@Before用于定义前置通知,相当于BeforeAdvice
@AfterReturning用于定义后置通知,相当于AfterReturningAdvice
@Around用于定义环绕通知,相当于MethodInterceptor
@AfterThrowing用于定义抛出通知,相当于ThrowAdvice
@After用于定义最终final通知,不管是否异常,该同志都会执行。
@DeclareParents用于定义引介通知,相当于IntroductionInterceptor

3.2、启用

1、使用@Configuration和@EnableAspectJAutoProxy

@Configuration
@EnableAspectJAutoProxy
public class Appconfig{}

2、基于XML配置

<aop:aspectj-autoproxy>

3.3、定义切面@Aspect

AspectJ类和其他普通的Bean一样,可以有方法和字段,不同的是AspectJ类需要@Aspect注解

@Aspect
public class AspectModule{}

Aspect类也可以像其他Bean一样在XML中配置

<bean id="myAspect" class="com.jsonliu.AspectModule" />

3.4、定义切入点

@Pointcut需要一个切入点

@Pointcut("execution(* com.jsonliu..*.*(..))")
private void myPointCut(){}

XML中配置:

<aop:pointcut expression="execution(* com.jsonliu..*.*(..))" id="myPointCut" />

3.5、定义通知advice

@Aspect支持5中类型advice,例如:

@Before("myPointCut()")
public void beforeAdvice(){}

3.6、实例

@Aspect
public class Logging {

    @Pointcut("execution(* com.jsonliu.bean.*.*(..))")
    private void selectAll(){}

    @Before("selectAll()")
    public void beforeAdvice(){
        System.out.println("前置通知");
    }

    @After("selectAll()")
    public void afterAdvice(){
        System.out.println("后置通知");
    }

    @AfterReturning(pointcut = "selectAll()",returning = "retVal")
    public void afterReturningAdvice(Object retVal){
        System.out.println("返回值为:"+retVal.toString());
    }

    @AfterThrowing(pointcut = "selectAll()",throwing = "ex")
    public void afterThrowingAdvice(IllegalArgumentException ex){
        System.out.println("异常信息:"+ex.toString());
    }

}
public class Man {
    private String name;
    private Integer age;

    public Man() {
        System.out.println("Man的无参构造函数");
    }

    public Man(String name, Integer age) {
        System.out.println("Man的有参构造函数");
        this.name = name;
        this.age = age;
    }

    public void show(){
        System.out.println("名称:"+name+",年龄:"+age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void throwException(){
        System.out.println("Man抛出异常");
        throw new IllegalArgumentException();
    }
}

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

    <aop:aspectj-autoproxy />

    <bean id="logging" class="com.jsonliu.aspect.Logging"/>

    <bean id="man" class="com.jsonliu.bean.Man">
        <property name="name" value="天下"/>
        <property name="age" value="1000" />
    </bean>

</beans>
public class TestAop {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("AspectBeans1.xml");
        Man man = (Man) context.getBean("man");
        man.getName();
        man.getAge();
        man.throwException();
    }
}

运行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑谈子云亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值