面向对象–OOP,针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分
面向切面–AOP(Aspect Oriented Programming):针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异
AOP使用场景:日志记录,权限,跟踪,优化和监控,事物的处理,资源池(如数据库连接池),系统的异常捕获和处理
aop是一种思想,一种思路,一种模式
而aspectJ则是实现了这AOP思想的框架,
为了理解AOP
以下以实现打印输出各类执行方法的时间以及内容输出到控制台为例,
例子:
问题:
有一个Person类,具有一个方法是eat(String food),我想要在执行eat方法的时候,将执行时的时间和方法名输出到控制台
Person.java
package models;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
//@Getter: 生成get方法,是类、成员变量注解。
//@Setter: 生成set方法,是类、成员变量注解。
//@Data: 生成get、set方法、空构造器、toString方法、equals方法、hashCode方法,是类注解。AppLombokDto 类的注解换成@Data试试。
//@ToString: 生成toString方法,是类注解。
//@EqualsAndHashCode:生成equals方法、hashCode方法,是类注解。
@Data
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(String food){
System.out.println(this.name+" is having "+food);
}
}
有什么思路呢?
思路一:直接改方法代码(最笨最直接的方法)
在该类的方法执行时,添加输出语句,打印当前时间和方法名
即eat方法变为如下:
public void eat(String food){
System.out.println(new Timestamp(System.currentTimeMillis())+
" "+this.getClass().getName()+" ,method eat");
System.out.println(this.name+" is having "+food);
}
效果:
但是,如果有很多个类都需要打印输出这个时间呢?就需要在每一个类的方法中添加代码打印输出时间
思路二:继承
继承,在子类中重写父类方法,加上时间输出(子类是父类功能的增强,多了日志功能)
新建类PersonLog,继承自类Person
PsersonLog.java
public class PersonLog extends Person {
public PersonLog(String name, int age) {
super(name, age);
}
@Override
public void eat(String food){
// 这里只输出时间
System.out.println(new Timestamp(System.currentTimeMillis())+
" "+this.getClass().getName()+" ,method eat");
super.eat(food);
}
@Override
public void run(){
System.out.println(new Timestamp(System.currentTimeMillis())+
" "+this.getClass().getName()+" ,method run");
super.run();
}
效果:
思考:思路二似乎还是需要在很多的地方去添加时间输出语句,灵活性很低,也没有复用代码的可能,如果能够对所有类的所有方法都实用,只需要一个专门用来输出任意方法的方法名和执行的时间的呢?
思路三:使用aop的思想,(动态代理机制)
代码实现时,不知道要代理的对象具体是什么,在代码运行时,通过反射,获取对象的方法和属性,加以一些处理
新建动态代理类:TimeLog,专门用来输出被代理对象的方法执行前后得到时间
TimeLog.java 需要实现 InvocationHandler接口
代码如下“
public class TimeLog implements InvocationHandler {
Object realObject;//被代理对象
public TimeLog(Object realObject