您的位置:首页 > 编程语言 > Java开发

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

2017-06-24 11:49 597 查看
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>
4000
;
<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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: