spring中基于注解的aop实用开发

aop是面向切面编程的意思,是相对于面向对象的另一种编程方法,

本文将介绍在spring中使用aspectj基于注解的aop实用开发。

一、关键点

1、aop配置,在xml配置文件中,通过aop:aspectj-autoproxy,加载springAop配置,

特别需要注意其中的属性proxy-target-class和expose-proxy的定义:

a)proxy-target-class,是否使用cglib代理,默认值false

当为false,表示使用jdk动态代理(必须实现接口);

当为true,表示使用cglib代理(直接对类代理,动态生成字节码);

b)expose-proxy,当类中方法相互调用时,是否对后续方法(方法有aop注解)支持aop,默认值false

当为false,不支持,也就是说此时当前类中方法互相调用,除首方法外,后续调用方法即使有aop注解,也不会有aop效果;

当为true,支持,也就是说此时当前类中方法互相调用,当后续调用方法有aop注解,就会有aop效果,

注意,调用方法需要指定当前调用的实例,且写法类似于(MeetService)AopContext.currentProxy()。

2、切面的编写,或者说处理类的编写,类上加@Aspect及@Component注解,接下来是三种处理方式:

a)@Before ,切点前处理,加在处理方法上,同时内加切点参数,即切点的注解,如@Before("@annotation(hello)");

b)@Round ,切点前后处理,加在处理方法上,同时内加切点参数,即切点的注解;

c)@After ,切点后处理,加在处理方法上,同时内加切点参数,即切点的注解;

另外,从方法参数JoinPoint(before或after)和ProceedingJoinPoint(around)获取切点的方法签名,从而获取切点方法各种信息;

从注解参数可以获取aop注解传递的信息。

二、实例

1、添加maven依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-asm</artifactId>
    <version>3.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.4</version>
</dependency>
2、添加spring配置spring-aop.xml

<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true" />
3、定义aop注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Hello {
    String helloStyle() default "";
}
4、定义aop注解操作

@Aspect
@Component
public class HelloHandler {

    /**
     * 切点前操作
     * @param joinPoint
     * @param hello
     */
    @Before("@annotation(hello)")
    public void beforeHello(JoinPoint joinPoint,Hello hello){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();  //获取注解对应方法的方法签名
        Method method = signature.getMethod();  //获取注解对应的方法
        System.out.println("beforeHello method name : "+ method.getName()+" helloStyle : "+ hello.helloStyle());
    }
    
    /**
     * 切点前后操作
     * @param pjp
     * @param hello
     * @return
     * @throws Throwable
     */
    @Around("@annotation(hello)")
    public Object aroundHello(ProceedingJoinPoint pjp , Hello hello) throws Throwable {

        String result = (String) pjp.proceed();  //执行方法,并获取方法返回结果
        System.out.println("aroundHello result is :"+result);

        result = hello.helloStyle() + " , "+ result;  //加工处理方法结果
        return result;
    }

    /**
     * 切点后操作
     * @param joinPoint
     * @param hello
     */
    @After("@annotation(hello)")
    public void afterHello(JoinPoint joinPoint,Hello hello){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("afterHello method name : "+ method.getName()+"  helloStyle : "+ hello.helloStyle());
    }
}
5、定义服务接口

public interface MeetService {
    String meet(String name);
    String meet1(String name);
}
6、定义服务实例

@Service("meetService")
public class MeetServiceImpl implements MeetService {

    @Hello(helloStyle = "hi")
    public String meet(String name){
        return name;
    }

    public String meet1(String name){
        try{
            MeetService meetService = (MeetService)AopContext.currentProxy();  //获取当前类的代理实例
            String result = meetService.meet(name)+1;  //调用当前类方法
            return result;
        }catch (Exception e){

        }
        return meet(name);
    }
}
7、测试

public class SpringAopMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
        MeetService meetService = context.getBean(MeetService.class);

        String result = meetService.meet("apple");  //调用有aop注解的方法
        System.out.println("main invoke meet result : "+result);

        System.out.println("---------------------------------------------------------------");

        result = meetService.meet1("banana");  //调用方法(可以有aop注解),同时方法内又调用了当前类方法且含有aop注解
        System.out.println("main invoke meet result : "+result);
    }

}
运行结果:

beforeHello method name : meet helloStyle : hi
aroundHello result is :apple
afterHello method name : meet  helloStyle : hi
main invoke meet result : hi , apple
---------------------------------------------------------------
beforeHello method name : meet helloStyle : hi
aroundHello result is :banana
afterHello method name : meet  helloStyle : hi
main invoke meet result : hi , banana1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值