博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring-aop学习【基于注解】
阅读量:5906 次
发布时间:2019-06-19

本文共 8314 字,大约阅读时间需要 27 分钟。

我个人觉得,这个好像就是用在定制日志输出上,和log4j很像。

用途:

如果业务方法调用每一步都需要详细的日志,那就用这个吧

好处就是:

方便维护,只包含业务代码

下面开始说明:

所需要的jar包:

com.springsource.net.sf.cglib-2.2.0.jar

com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

直接上代码:

声明一个接口

package com.spring.bean.aop;import java.util.List;/** *  * @author Administrator * */public interface UserService {//    打招呼    void say();//    获取年龄    int getValue(List
array,int index);}

这是接口的实现类

package com.spring.bean.aop;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** *  * @author Administrator *      实现类 */@Service("userService")public class UserServiceImpl implements UserService {    /**     * 自动装配use对象     */    @Autowired    private User user;    @Override    public void say() {        // TODO Auto-generated method stub        System.out.println("我叫"+user.getName()+",今年"+user.getAge()+"岁,你好!!");    }        @Override    public int getValue(List
array, int index) { // TODO Auto-generated method stub return array.get(index); }}

用户对象信息

package com.spring.bean.aop;import org.springframework.stereotype.Component;/** * @author Administrator *      用户信息 */@Componentpublic class User {    String name;    int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

然后是两个切面代码

package com.spring.bean.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * 声明一个切面 * @author Administrator * */ //order可以指定哪个切面先执行,数值越小,优先执行 @Order(1)@Aspect@Componentpublic class MyLoggingAspectj {        //    声明一个切入点    @Pointcut("execution(* *(..))")    public void pointcut(){            }    /**     * 前置通知,该方法执行在被调用方法之前     * @param joinPoint     */    @Before("pointcut())")    public void beforeMethod(JoinPoint joinPoint){//        获得调用的方法名        String methodName = joinPoint.getSignature().getName();        Object[] args = joinPoint.getArgs();        System.out.println("MyLoggingAspectj the method "+methodName+"begins with "+Arrays.asList(args));    }        } 第二个切面代码
package com.spring.bean.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * 声明一个切面 * @author Administrator * */@Order(2)@Aspect@Componentpublic class LoggingAspectj {        //    声明一个切入点    @Pointcut("execution(* *(..))")    public void pointcut(){            }/*    *//**     * 前置通知,该方法执行在被调用方法之前     * @param joinPoint     *//*    @Before("pointcut())")    public void beforeMethod(JoinPoint joinPoint){//        获得调用的方法名        String methodName = joinPoint.getSignature().getName();        Object[] args = joinPoint.getArgs();        System.out.println("the method "+methodName+"begins with "+Arrays.asList(args));    }        *//**     * 后置通知     * 该方法执行在被调用方法之后,报错也依然执行     * @param joinPoint     *//*    @After("pointcut())")    public void afterMethod(JoinPoint joinPoint){//        获得调用的方法名        String methodName = joinPoint.getSignature().getName();        Object[] args = joinPoint.getArgs();        System.out.println("the method "+methodName+"Ends with "+Arrays.asList(args));    }        *//**     * 返回通知, 在方法返回结果之后执行,异常无返回值     * @param joinPoint     *//*    @AfterReturning(value="pointcut())",returning="result")    public void afterReturning(JoinPoint joinPoint,Object result){//        获得调用的方法名        String methodName = joinPoint.getSignature().getName();        Object[] args = joinPoint.getArgs();        System.out.println("the method "+methodName+"afterReturning with "+Arrays.asList(args)+"  ["+result+"]");    }        *//**     * 异常通知     * 在方法抛出异常之后     * @param joinPoint     *//*    @AfterThrowing(value="pointcut()",throwing="e")    public void afterReturning(JoinPoint joinPoint,Exception e){//        获得调用的方法名        String methodName = joinPoint.getSignature().getName();        Object[] args = joinPoint.getArgs();        System.out.println("the method "+methodName+"afterThrowing with "+Arrays.asList(args)+e);    }*/        /**     * 环绕通知需要配合ProceedingJoinPoint使用,相当于动态代理     * @param pjp     * @return     */    @Around(value="pointcut()")    public Object aroundMethod(ProceedingJoinPoint pjp) {        // 获得调用的方法名        String methodName = pjp.getSignature().getName();        Object result = null;        // 调用目标方法        try {            // 前置通知            System.out.println("the method " + methodName + "Begins with " + Arrays.asList(pjp.getArgs()));            result = pjp.proceed();            // 后置通知            System.out.println("the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()));            // 后置有返回值            System.out.println(                    "the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()) + " [" + result + "]");        } catch (Throwable e) {            // TODO Auto-generated catch block            // 异常通知            System.out.println("the method " + methodName + "AfterThrowing with " + Arrays.asList(pjp.getArgs()) + e);            // e.printStackTrace();            // 不加这句,会报错,因为result返回值为null            throw new RuntimeException(e);        }        System.out.println("the method " + methodName + "LastEnds with " + Arrays.asList(pjp.getArgs()));        return result;    }        }
 

测试代码:

package com.spring.bean.aop;import java.util.ArrayList;import java.util.List;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {    public static void main(String[] args) {        // TODO Auto-generated method stub        ApplicationContext ctx=new ClassPathXmlApplicationContext("bean-aop.xml");        UserService userServiceImpl=(UserService) ctx.getBean("userService");        User user=(User) ctx.getBean("user");        List
arrayList = new ArrayList
(); arrayList.add(1); arrayList.add(2); int age = userServiceImpl.getValue(arrayList, 1); user.setName("xiaoqiang"); user.setAge(age); userServiceImpl.say(); }}

bean文件

 

 总结: 1.在pom文件添加依赖,在 Spring 的配置文件中加入 aop 的命名空间。 
org.aspectj
aspectjrt
${aspectj.version}
org.aspectj
aspectjweaver
${aspectj.version}
 

2.为接口实现类添加注解@Component

3.编写一个切面类,配置切面

* 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.spring.bean.aop"></context:component-scan>

* 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

* 为匹配的类自动生成动态代理对象.

4.编写前置通知方法,在方法上方添加注解

// 表达式注意格式: 修饰 +方法(有无返回)+包名+类名+方法名+参数

  @Before("execution(public int com.spring.bean.annotation.aopimpl.Calculation.sub(int, int))")

* @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体.

* @Before 里面的是切入点表达式:

如关注详细参数,添加joinpoint对象,可以访问到方法的签名和参数

 

转载地址:http://jycpx.baihongyu.com/

你可能感兴趣的文章
抓屏原理
查看>>
UNIX网络编程读书笔记:TCP输出、UDP输出和SCTP输出
查看>>
扩展 DbUtility (1)
查看>>
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
查看>>
Hadoop学习笔记系列文章导航
查看>>
SpringMVC中ModelAndView addObject()设置的值jsp取不到的问题
查看>>
Prometheus : 入门
查看>>
使用 PowerShell 创建和修改 ExpressRoute 线路
查看>>
在C#中获取如PHP函数time()一样的时间戳
查看>>
Redis List数据类型
查看>>
大数据项目实践(四)——之Hive配置
查看>>
初学vue2.0-组件-文档理解笔记v1.0
查看>>
上传图片预览
查看>>
lagp,lacp详解
查看>>
LVS之DR模式原理与实践
查看>>
Docker的系统资源限制及验证
查看>>
c++ ios_base register_callback方法使用
查看>>
Java中为什么需要Object类,Object类为什么是所有类的父类
查看>>
angularjs-paste-upload
查看>>
linux基础命令 head
查看>>