美文网首页
Aop 面向切面的编程

Aop 面向切面的编程

作者: 我是邱邱 | 来源:发表于2018-09-09 15:45 被阅读0次

实现Aop的方式有两种:

1.xml配置文件方式

首先写出目标类,目标类中有目标方法即切入点,例如

@Repository
public class Dao implements IDao{

    @Override
//  切入点
    public void add() {
        // TODO Auto-generated method stub
        System.out.println("add info");
    }

    @Override
    public void delete() {
        // TODO Auto-generated method stub
        System.out.println("delete info");
    }

}

其次,需要有自己的切面类,切面类中包含关注点:例如

// 切面类
@Component
public class LogAop {
    // 关注点
    // 参数 JoinPoint ,切入点对象,根据实际需求,可写可不写
    public void begin(JoinPoint jp){
        System.out.println("befor");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        // 方法名
        String name = jp.getSignature().getName();
        // 类名
        String cName = jp.getSignature().getDeclaringTypeName();
        //jp.getArgs();//获取方法的参数
        
        System.out.println("开始执行方法:" + cName + "." + name + ",执行时间:" + sdf.format(new Date()));
//      System.out.println("执行时间:" + sdf.format(new Date()));
    }
    
    public void end(){
        System.out.println("after");
    }
    
    // 正常返回通知要执行的方法
    public void afterReturn(){
        System.out.println("after return");
    }
    
    // 环绕通知要执行的方法,必须要使用ProceedingJoinPoint 参数,表示切入点信息的对象
    public void around(ProceedingJoinPoint pjp){
        // 获取执行的方法的方法名
        System.out.println("around befor:" + pjp.getSignature().getName());
        try {
            // 执行目标方法
            pjp.proceed();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("around after");
    }
    
}

再者,需要在bean.xml配置文件中配置引入切面类,配置如下:

<!--扫描相关注解,即扫描例如@Component这些注解  -->
        <context:component-scan base-package="xmlaop"></context:component-scan> 
        
        <!--针对aop的配置  -->
        <aop:config>
            <!--配置切入点  ,配置切入点表达式 
                execution(访问权限 包名.类名.方法名(参数));
                第一个*表示所有的访问的权限
                第二个*(..)表示的任意方法名,任意参数
                本例子中,Dao类中所有的方法都是切入点
            -->
            <aop:pointcut expression="execution(* xmlaop.Dao.*(..))" id="pc"/>
            <!--配置切面类  ref:引入一个对象
                method:前置通知要执行的方法
                point-cut:切入点的引用
             -->
            <aop:aspect ref="logAop">
            <!--前置通知  -->
                <aop:before method="begin" pointcut-ref="pc"/>
            <!--后置通知  -->
                <aop:after method="end" pointcut-ref="pc"/>
            <!--正常返回通知  -->
                <aop:after-returning method="afterReturn" pointcut-ref="pc"/>
            <!--环绕通知  -->
                <aop:around method="around" pointcut-ref="pc"/>
            </aop:aspect>
        </aop:config> 

2.注解方式

还可以直接在切面类上使用注解的方式配置切入点
首先,还是先写目标对象,即目标对象中有目标方法即切入点

@Component
public class Dao implements IDao{

    @Override
    // 切入点
    public void add() {
        // TODO Auto-generated method stub
        System.out.println("add info");
    }

    @Override
    public void delete() {
        // TODO Auto-generated method stub
        System.out.println("delete info");
    }

}

其次,写出切面类,直接使用注解的方式在关注点上面配置切入点

//动态扩展功能
//切面类
@Component
//表示修饰的类是一个切面类
@Aspect
public class LogAop {
//  如果所有的通知使用相同的切入点,就需要额外定义一个方法
    @Pointcut("execution(* annoaop.Dao.*(..))")//配置切入点
    public void pointcut() {
        
    }
//关注点(通知,增强)
//  参数可以不写,JoinPoint获取切入点接口对象,即可以获取执行的方法名
//  @Before("execution(....)")
    @Before("pointcut()")//通过配置切入点的方法名来引用相关的切入点
    public void begin(JoinPoint joinPoint) {
        System.out.println("before");
//      方法执行之前
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getSignature().getDeclaringTypeName();
        
        String string = format.format(new Date());
        System.out.println(string + "开始执行;" + methodName + ";" + className);
    }
    
    @After("pointcut()")//后置通知
    public void end() {
        System.out.println("after");
    }
//  正常返回通知执行的方法
    @AfterReturning("pointcut()")
    public void afterReturn() {
        System.out.println("after return");
    }
//  环绕通知必须给参数,且必须使用ProceedingJoinPoint的参数,表示的是切入点信息
    @Around("pointcut()")
    public void around(ProceedingJoinPoint point) {
//      获取执行方法的方法名
        System.out.println("around before" + point.getSignature().getName());
        try {
//          执行目标方法
            point.proceed();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("around after");
    }
}

再者,在配置文件中扫描相关的注解

<!--扫描相关注解  只会扫描依赖注入以及控制反转的代码-->
        <context:component-scan base-package="annoaop"></context:component-scan> 
       
 <!--扫描aop的注解  -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

相关文章

网友评论

      本文标题:Aop 面向切面的编程

      本文链接:https://www.haomeiwen.com/subject/lzfdgftx.html