springAOP-使用注解创建切面

1 目标对象

package com.musi.bean;
import org.springframework.stereotype.Component;
@Component
public class Animal {

    public void run(){
        System.out.println("animal is running .....");
    }

    public void run(String  name){
        System.out.println(name+" is running ........");
    }

    public void run(int times){
        System.out.println("animal running times:"+times);
    }
}

2 切面

package com.musi.aop.annotationaspect;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnimalAspect {

    @Before("execution(* com.musi.bean.Animal.run(..))")
    public void beforeRunning(){
        System.out.println("annotation before running .......");
    }

    @After("execution(* com.musi.bean.Animal.run(..))")
    public void afterRunning(){
        System.out.println("annotation after running .......");
    }

    @AfterReturning("execution(* com.musi.bean.Animal.run(..))")
    public void afterReturning(){
        System.out.println("annotation afterReturning running .......");
    }

    @AfterThrowing("execution(* com.musi.bean.Animal.run(..))")
    public void afterThrowing(){
        System.out.println("annotation afterThrowing running .......");
    }
}

简化写法:

package com.musi.aop.annotationaspect;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnimalAspectSimple {

    @Pointcut("execution(* com.musi.bean.Animal.run())")
    public void run(){}

    @Before("run()")
    public void beforeRunning(){
        System.out.println("before running .......");
    }

    @After("run()")
    public void afterRunning(){
        System.out.println("after running .......");
    }

    @AfterReturning("run()")
    public void afterReturning(){
        System.out.println("afterReturning running .......");
    }

    @AfterThrowing("run()")
    public void afterThrowing(){
        System.out.println("afterThrowing running .......");
    }
}

备注:上述代码中使用了@Pointcut注解,其中performance()方法的名称和实际内容并不重要,在这里它实际上应该是空的,它本身只不过是一个标识,供@Pointcut注解依附.需要注意的是此时除了注解和没有实际操作的performance()方法,Audience类依然是一个pojo,这与普通的Java类并没有什么区别,只不过通过注解表名会被最为切面使用.

3 如果就此止步的话,Audience只会是spring容器中普通的bean,即便使用了AspectJ,但它并不会被视为切面,还需要另作配置.使用Javaconfig的话,可以在配置类的类级别上通过使用EnableAspectJ-AutoProxy注解启用自动代理功能,代码如下:

package com.musi.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.musi")
public class SystemConfig {

}

相应的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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.musi"/>
    <aop:aspectj-autoproxy />

</beans>

4 测试类

package com.musi.test.bean;

import com.musi.aop.annotationaspect.Encoreable;
import com.musi.bean.Animal;
import com.musi.config.SystemConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SystemConfig.class)
public class SpringBeanTest {

    @Autowired
    private Animal animal;

    @Test
    public void test(){
        animal.run();
    }
}

使用xml配置时的测试类

package com.musi.test.bean;

import com.musi.bean.Animal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:application.xml"})
public class SpringXmlTest {
    @Autowired
    private Animal animal;

    @Test
    public void test(){
        animal.run();
    }
}

5 创建环绕通知

package com.musi.aop.annotationaspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnimalRoundAspect {
    @Pointcut("execution(* com.musi.bean.Animal.run(..))")
    public void run(){}

    @Around("run()")
    public void aroundRunning(ProceedingJoinPoint pjp){
        try {
            System.out.println("around before ....");
            pjp.proceed();
            System.out.println("around after ....");
        }catch (Throwable throwable) {
            System.out.println("around trowing ....");
            throwable.printStackTrace();
        }
    }
}

测试类同上

6 处理通知中的参数

package com.musi.aop.annotationaspect;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnimalArgsAspect {

    @Pointcut("execution(* com.musi.bean.Animal.run(int))&&args(times)")
    public void run(int times){}

    @Before("run(times)")
    public void beforeRunning(int times){
        System.out.println("before running times:"+times);
    }

    @After("run(times)")
    public void afterRunning(int times){
        System.out.println("after running times:"+times);
    }

    @AfterReturning("run(times)")
    public void afterReturning(int times){
        System.out.println("afterReturning running times:"+times);
    }

    @AfterThrowing("run(times)")
    public void afterThrowing(int times){
        System.out.println("afterThrowing running times:"+times);
    }
}

测试类

package com.musi.test.bean;

import com.musi.bean.Animal;
import com.musi.config.SystemConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SystemConfig.class)
public class SpringBeanArgsTest {

    @Autowired
    private Animal animal;

    @Test
    public void test(){
        animal.run(11);
    }
}

7 通过注解引入新功能

  1. 创建引入的代理
package com.musi.aop.annotationaspect;

public interface Encoreable {
    void jump();
}
  1. 代理默认实现类
package com.musi.aop.annotationaspect;

public class EncoreableImpl implements Encoreable {
    public void jump() {
        System.out.println("this is EncoreableImpl.....");
    }
}

3)通过DeclareParents设置代理

package com.musi.aop.annotationaspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class EncoreableIntroducer  {

    @DeclareParents(value="com.musi.bean.Animal",defaultImpl=EncoreableImpl.class)
    public static Encoreable encoreable;
}

说明:@DeclareParents注解有三部分组成:
value属性指定了哪种类型的bean要引入该接口.在本例中也就是Animal.(如果Animal是接口的话可以在Animal后加上加号,即"com.musi.bean.Animal+",表示是Animal的所有子类型,而不是Animal本身)
defaultImpl属性指定了为引入功能提供实现的类.在这里我们指定的是DefaultEncoreable提供实现
@DeclareParents注解所标注的静态属性指明了要引入接口.在这里我们引入的是Encoreable接口.
此外,我们需要将EncoreableIntroducer声明为一个bean:

4)测试类

package com.musi.test.bean;

import com.musi.aop.annotationaspect.Encoreable;
import com.musi.bean.Animal;
import com.musi.config.SystemConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SystemConfig.class)
public class SpringBeanTest {

    @Autowired
    private Animal animal;

    @Test
    public void test(){
        animal.run();
        Encoreable encoreable = (Encoreable)animal;
        encoreable.jump();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值