AOP编程(Aspect Oriented Programming)面向切面/方面编程
优点:
可以动态将一个组件功能切入到指定的目标方法上。
可以使结构更加灵活,也能实现组件的重复利用。
OOP:面向对象编程,侧重点对象设计
AOP:面向切面编程,侧重点切面
AOP:更注重于业务逻辑隔离,将一些共通处理逻辑和传统处理逻辑解耦。
共通:事务处理,日志记录,异常处理;
传统:增删改查
适应环境:
共通的处理逻辑
调用时机相同
XML方法:
<!--组件 -->
package org.tarena.note.aspect;
public class NoteLogger {
public void clogger(){
System.out.println("进入Controller处理");
}
}
<!--applicationContext.xml -->
<!-- AOP示例 -->
<!-- 将noteLogger放在容器中 -->
<bean id="noteLogger" class="org.tarena.note.aspect.NoteLogger">
</bean>
<aop:config>
<!-- 将noteLogger定义为切面组件(封装的共同功能) -->
<aop:aspect ref="noteLogger">
<!-- 作用在什么时候,向哪些方法上切 -->
<aop:before method="clogger" pointcut="within(org.tarena.note.controller..*)"/>
</aop:aspect>
</aop:config>
注解方法:
<!-- 组件 -->
package org.tarena.note.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component//扫描,将组件扫描到Spring容器
@Aspect//将当前组件设置为切面组件
public class ServiceLogger {
@Before("within(org.tarena.note.service..*)")
public void slogger(){
System.out.println("进入Service处理");
}
}
<!-- applicationContext.xml -->
<!-- 开启AOP注解支持,@Aspect,@通知标记 -->
<aop:aspectj-autoproxy />
注意:
1.要切入什么功能–>切面(Aspect)
2.什么时候切入–>通知(Advice)
前置通知@Before
后置通知@AfterReturning
异常通知@AfterThrowing
最终通知@After
环绕通知:前置+后置
3.往哪些组件方法切入–>切入点(Pointcut)
--类型限定表达式
within(类型)//与类型匹配的组件都是目标
within(org.service.UserService)
within(org.service.*)//org.service包下的
within(org.service..*)//org.service包及其子包下的
--方法限定表达式
execution(方法修饰符(可有可无) 返回类型 方法名(参数) 抛出异常(可有可无))
execution(public List findById(String s) throws Exception)
execution(* find*(..))//..代表0到多个参数
上述表达式可以使用!,&&,||运算符连接
====案例====
云笔记:异常处理,当发生异常,将异常信息记录到文件中
a.切入的功能:将异常ixnxi写文件
b.切入的时机:出现异常调用@AfterThrowing
c.往哪些组件方法切入:往Controller组件追加within(org.tarena.note.controller..*)
package org.tarena.note.aspect;
import java.io.FileWriter;
import java.io.PrintWriter;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class ExceptionLogger {
@AfterThrowing(throwing="e",pointcut="within(org.tarena.note.controller..*)")
public void log(Exception e){
//将异常信息写入文件
System.out.println("记录异常信息:"+e);
try {
FileWriter fw = new FileWriter("D:\\BaiduYunDownload\\error.txt");
PrintWriter out = new PrintWriter(fw);
e.printStackTrace(out);
out.flush();
out.close();
fw.close();
} catch (Exception e1) {
System.out.println("记录异常信息失败");
}
}
}