面向切面编程,将扩展的逻辑形成组件类,提供方法,类似于将方法加入到原代码中,但是不用修改原代码任何逻辑
原理:动态代理技术
在spring中,框架会根据目标类是否实现了接口来决定采用哪种动态代理方式
一、目标对象实现接口,使用JDK动态代理
特点:
1、代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们提供目标对象所实现的接口的字节码对象)
2、动态代理要求目标对象一定要实现接口,所以也叫做接口代理!
步骤:
1、需要存在抽象角色,定义所有的功能
2、真实对象实现抽象角色的所有功能
3、通过Proxy类,创建代理对象,调用代理方法
4、在InvocationHandler的invoke对代理的方法有选择的修改或不修改、添加执行条件等
二、目标对象没有实现接口,使用CGLIB代理(Spring AOP)
使用要求:
代理的类不能为final,否则报错
目标对象的方法如果为final/static,那么便不会被拦截,即不会执行代理,而是直接执行目标业务方法
Joinpoint(连接点):
在程序执行过程中,需要拦截的方法
根据规则,可以指定拦截的方法,每一个被拦截的方法称为连接点
Pointcut(切入点):
切入点,就是拦截方法设置的规则,连接点的一系列集合
切入点就是指要对哪些连接点进行拦截的定义
切面组件:
<bean id="logAspect" class="com.qt.aspect.LogAspect"></bean>
配置: <aop:config> <aop:aspect ref="logAspect"> </aop:aspect> </aop:config>
expression:设置切入点表达式
withing(包名.类名):指定作用某些类中的所有方法
execution(修饰词 包名.类名.方法名(参数列表)):指定作用某些类的某些方法
支持通配符:
? 表示任意一个字符
表示任意多个字符 `com.qt.service.Impl<br />.. 表示包和子包com..EmpServiceImpl`
纯注解方式配置:
// 日志类@Component@Aspect // 标记为切面组件 替代aop:aspectpublic class LogAspect {/*** 定义切入点* 必须用在方法上面,需要定义一个空实现方法* 需求:给所有服务层的类中的某些方法设置切入点* execution(修饰词 包名.类名.方法名()):某些类的某些方法,最后面一定是方法* 方法名(..):表示任意的参数个数和类型,如需指定参数,只需要写参数类型*/@Pointcut("execution(* com..*Impl.save(..))") // aop:pointcutpublic void pointcut(){ }@Before("pointcut()") // value值使用上面的空实现方法(也可以直接使用execution...)public void before() {System.out.println("前置通知,记录日志。。。");}// 配置类@Configuration@ComponentScan(basePackages = "com.qt")@EnableAspectJAutoProxy // 开启aop注解支持,代替<aop:aspectj-autoproxy>public class SpringConfig {}
Advice(通知/增强):
增强连接点的实现代码(也就是需要为连接点绑定的方法)
所谓通知是指拦截到连接点之后所要做的事情
通知的类型:
前置通知(Before):执行连接点方法之前执行,方法执行前会先执行切面方法
返回通知(After-Returning):方法执行完毕后返回的时候执行,出现异常不执行
环绕通知(Around):方法执行前后分别执行的逻辑
最终通知(After):不管有无异常都会执行,相当于try…catch…finally中的finally代码块
异常通知(AfterThrowing):出现异常后执行 throwing设置异常对象,与方法参数名一致
pointcut-ref:引用前面定义的切入点对象
pointcut=”” :当前通知有效的切入点表达式
method:通知需要调用的切面组件的方法
target(目标对象):
被代理对象,连接点的所属方法,也就是需要增强的方法
Weaving(织入):
将通知应用到连接点形成切入点的过程→Aspect
Proxy(代理):
一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面):
拦截器处理类,切入点+通知
三、日志
使用步骤:
1、引入依赖 log4j 和 slf4j
log4j是apache的子项目,用于系统的日志记录功能
2、配置日志配置文件
常见两种配置方式: properties 和 xml
默认从类路径下读取的 log4j.xxx 方式命名的配置文件
配置完成后,框架等自己的日志记录便可以正常工作
3、在需要进行日志记录功能代码上增加日志记录逻辑


日志文件配置:
1、设置日志根: 日志根=日志级别,输出目的地1,输出目的地2...
级别:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL(右边的的会输出左边的)
2、设置输出目的地: log4j.appender.输出目的地变量名=输出目的地类
输出目的地变量名应与日志根的输出目的地名一致
3、设置输出文件位置: log4j.appender.输出目的地变量名.File=文件存放位置
4、设置日志信息布局:log4j.appender.输出目的地变量名.layout=日志信息布局类
·
