【Spring】—— AOP原理及项目应用

  在应用AOP编程是主要编程对象是切面,而切面模块化横切关注点。仍然需要定义公共功能,但可以明明确的定义这个功能在哪里,以什么方式应用。并且不必修改受影响的类。这样一来横切关注点就被模块化到特殊的对象(切面)里了。

AOP术语

切面(Aspect):横切关注点

通知(Advice):切面必须要完成的工作

目标(Target):被通知的对象

代理(Proxy):向目标对象应用通知之后创建的对象

 

使用配置

1)加入jar包

《【Spring】—— AOP原理及项目应用》

 

2)在配置文件中加入aop命名空间

3)基于注解的方式

在配置文件中加入如下配置

《【Spring】—— AOP原理及项目应用》

把横切关注点的代码出现到切面的类,切面首先要是一个IOC中的bean,加入@component注解

切面还需要加入@Aspect注解

4)在类中声明各种通知。

1、声明一个方法。

2、在方法前加入一个注解

3、可以在方法汇总加入一JoinPoint,可以获取一些方法的参数和方法名

 

AspectJ支持5种类型的通知注解

@Before:前置通知, 在方法执行之前执行

@After:后置通知, 在方法执行之后执行

@AfterRunning:返回通知, 在方法返回结果之后执行

@AfterThrowing:异常通知, 在方法抛出异常之后

@Around:环绕通知, 围绕着方法执行

 

项目应用

 

应用场景,在项目中采用前后端分离。规定了前端接收的信息,但是前端无法接收具体的错误信息,这在开发过程中就很不方便。无法很快的定位消息。所以使用了spring的AOP对于开发情况会将错误信息返给前端。具体实现详见

 

Spring-mvc文件中引入对于aop的使用并且让spring管理起来

	<aop:aspectj-autoproxyproxy-target-class="true"/>
	<beanclass="com.dmsdbj.itoo.tool.aspect.AfterReturningAspect"/>

具体实现类,使用的事后置环绕,在方法之后执行

	@Aspect
	public class AfterReturningAspect {
	    private static final Logger logger = LoggerFactory.getLogger(AfterReturningAspect.class);
	
	    private final Map clazzMap = new HashMap<String, String>();
	    public AfterReturningAspect() {
	        reloadProperties();
	
	        //设置定时任务,定时加载属性配置文件
	        Timer timer = new Timer();
	        timer.schedule(new TimerTask() {
	            @Override
	            public void run() {
	                reloadProperties();
	            }
	        }, 1000, 60000);
	
	    }
	    /**
	     * 加载配置文件将其中你的key-value保存到clazzMap中
	     */
	    private void reloadProperties() {
	        Properties p = new Properties();
	        try {
	            InputStream in = new FileInputStream(this.getClass().getClassLoader().getResource("resource.properties").getFile());
	            p.load(in);
	        } catch (IOException e) {
	            logger.error("[AfterReturningAspect.getProperties()]the method of printing log is error", e.getMessage());
	        }
	
	        Enumeration en = p.propertyNames();
	        while (en.hasMoreElements()) {
	            String key = (String) en.nextElement();
	            String property = p.getProperty(key);
	            clazzMap.put(key, property);
	        }
	
	    }
	
	    /**
	     * 拦截controller将异信息抛给浏览器
	     * @param rvt  拦截到的Controller给前端返回的ItooResult型实体
	     */
	    @AfterReturning(returning = "rvt",pointcut = "execution(* com.dmsdbj.itoo.*.controller.*.*(..))")
	    public void log(Object rvt){
	        ItooResult result = (ItooResult)rvt;
	        if("true".equals(this.clazzMap.get("aop.printexception.enable")) && result.getException() instanceof Exception){
	            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
	            response.reset();
	            response.setCharacterEncoding("UTF-8");
	            response.setHeader("Content-Type", "text/plain;charset=UTF-8");
	            response.setHeader("icop-content-type", "exception");
	            throw new ItooRuntimeException(result.getException());
	        }
	    }
	}

不同的环境中aop.printexception.enable的值不相同,通过这个来判定是否会将错误信息抛到前端

《【Spring】—— AOP原理及项目应用》

    原文作者:AOP
    原文地址: https://blog.csdn.net/fjj15732621696/article/details/80715417
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞