1.aop概述
Spring的AOP:
什么叫做AOP:Aspect oritention programming(面向切面编程)
什么是切面:看图,业务方法 执行前后.
AOP的目的:
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,
便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
AOP的优势:
降低模块的耦合度、使系统容易扩展、更好的横切面代码复用性.
AOP当中的概念:
1、切入点(Pointcut):在哪些类,哪些方法上切入增强(where);
2、增强(Advice):早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后/出现异常)做什么(what:增强的功能);
3、切面(Aspect):切面=切入点+通知,通俗点就是:什么时机,什么地点,做什么!
4、织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。
Spring AOP开发依赖的jar:
spring-aop-4.1.2.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2.aop中的各种增强
各种不同的增强的时机:
aop:before(前置增强):在方法执行之前执行增强;
aop:after-returning(后置增强):在方法正常执行完成之后执行增强;
aop:throwing(异常增强):在方法抛出异常退出时执行增强;
aop:after(最终增强):在方法执行之后执行,相当于在finally里面执行;可以通过配置throwing来获得拦截到的异常信息
aop:around(环绕增强):最强大的一种增强类型。 环绕增强可以在方法调用前后完成自定义的行为,
要求:方法必须要返回一个Object(返回的结果)
3.aop的实际应用
3.1配置事务管理器
一步搞定:
<!-- 事务管理-->
<!-- 做什么 where-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 什么时候做 when -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!-- 什么地点做 where -->
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* com.day02.sation.service.impl.*Service.*(..))"/>
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
</aop:config>
3.2做日志系统
需求:在进入控制层前输出请求参数\请求时间等信息
在执行完成后输出执行结果与请求时间
a.编写打印日志类
package com.day02.sation.aop; import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Enumeration; /**
* Created by Administrator on 1/9.
*/
public class WebAspectLog {
private static final Logger logger = LoggerFactory.getLogger(WebAspectLog.class); /**
* 方法执行前输出
*/
public void beforeLog() {
logger.info("-----------beforeLog----------------");
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String key = parameterNames.nextElement();
String value = request.getParameter(key);
//输出 参数信息
logger.info(key + " = " + value);
}
Date date = new Date();
String requestURI = request.getRequestURI();
logger.info("[==> date=" + date + ", requestURI=" + requestURI +"]");
} /**
* 方法执行后输出
* @param returnObj
*/
public void afterLog(Object returnObj) {
logger.info("-----afterLog----");
String s = JSON.toJSONString(returnObj);
logger.info(" returnObj =" + s);
}
}
b.编写spring_aop.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--引入日志管理类-->
<bean id="webAspectLog" class="com.day02.sation.aop.WebAspectLog"/>
<!--配置切面-->
<aop:config>
<aop:aspect ref="webAspectLog">
<aop:pointcut id="pointcut" expression="execution(* com.day02.sation.controller.*Controller.*(..))"/>
<aop:before method="beforeLog" pointcut-ref="pointcut"/>
<!-- 注意如果要获取执行后的结果 必须配置参数 returning="对象为afterLog方法的参数对象名称"-->
<aop:after-returning method="afterLog" pointcut-ref="pointcut" returning="returnObj"/>
</aop:aspect>
</aop:config>
</beans>
c.日志配置文件 log4j.properties
日志配置将在后面详细讲解
#获取日志 INFO:表示获取日志的等级 A1:表示日志存器,可以自定义名称
log4j.rootLogger=INFO,A1 ########################控制台日志####################################
#sql日志
log4j.logger.com.day02.sation.dao=DEBUG
#定义日志A1存放器 log4j.appender.A1=org.apache.log4j.ConsoleAppender #输出到控制台 System.err System.out log4j.appender.A1.Target=System.out #配置日志输出格式 log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=[%p][%t][%d{yyyy-MM-dd HH\:mm\:ss}][%C][%L] - %m%n
日志系统主要逻辑完成,当然这里只是构建结构如果你要打印更多日志信息或者记录数据库在打印日志类中添加即可!