AOP(Aspect Oriented Programming)面向切面编程
OOP(Object Oriented Programming)面向对象编程,用对象化的思想来完成程序
AOP是OOP的一个补充,是在另一个维度上抽象出对象
具体是指程序运行时动态的将非业务代码切入到业务代码中,从而实现程序的解耦合,将非业务代码抽象成一个对象,对该对象编程就是面向切面编程。
AOP的优点:
在不进行松耦合的情况下,业务代码与非业务代码高度耦合在一起:
接口Cal
public interface Cal {public int add(int num1,int num2);public int sub(int num1,int num2);public int mul(int num1,int num2);public int div(int num1,int num2);
}
实现类CalImpl
import com.test.Cal;public class CalImpl implements Cal {@Overridepublic int add(int num1, int num2) {System.out.println("add方法的参数是:"+num1+","+num2);int result=num1+num2;System.out.println("add方法的结果是:"+result);return result;}@Overridepublic int sub(int num1, int num2) {System.out.println("sub方法的参数是:"+num1+","+num2);int result=num1-num2;System.out.println("sub方法的结果是:"+result);return result;}@Overridepublic int mul(int num1, int num2) {System.out.println("mul方法的参数是:"+num1+","+num2);int result=num1*num2;System.out.println("mul方法的结果是:"+result);return result;}@Overridepublic int div(int num1, int num2) {System.out.println("div方法的参数是:"+num1+","+num2);int result=num1/num2;System.out.println("div方法的记过是:"+result);return result;}
}
主类
public class Main {public static void main(String[] args) {Cal cal=new CalImpl();cal.add(10,3);}
}
原接口类和接口不变,实现类仅保留耦合前的代码
public class CalImpl implements Cal {@Overridepublic int add(int num1, int num2) {int result=num1+num2;return result;}@Overridepublic int sub(int num1, int num2) {int result=num1-num2;return result;}@Overridepublic int mul(int num1, int num2) {int result=num1*num2;return result;}@Overridepublic int div(int num1, int num2) {int result=num1/num2;return result;}
}
创建一个代理类MyInvocationHandler:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;public class MyInvocationHandler implements InvocationHandler {//委托对象private Object object=null;//返回代理对象public Object bind(Object object){this.object=object;return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//实现业务代码和非业务代码的解耦合System.out.println(method.getName()+"方法的参数是:"+ Arrays.toString(args));Object result=method.invoke(this.object,args);return result;}
}
主类:
public class Main {public static void main(String[] args) {//实例化委托对象Cal cal=new CalImpl();//获取代理对象MyInvocationHandler myInvocationHandler=new MyInvocationHandler();Cal proxy=(Cal)myInvocationHandler.bind(cal);proxy.add(10,3);proxy.sub(10,3);proxy.mul(10,3);proxy.div(10,3);}
}
代码达到松耦合的目的,运行后可以得到相同的结果
在maven的pom.xml文件中加入依赖
org.springframework spring-context 5.2.9.RELEASE org.springframework spring-aop 5.2.9.RELEASE org.springframework spring-aspects 5.2.9.RELEASE
spring.xml的bean文件中加入aop组件及自动扫包,aop:aspectj-autoproxy,Spring IoC容器会结合切面对象自动生成代理对象,AOP底层就是通过动态代理机制来实现的
创建切面接入的类LoggerAspect
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;import java.util.Arrays;@Component
@Aspect
public class LoggerAspect {@Before("execution(public int com.test.Impl.CalImpl.*(..))")public void before(JoinPoint joinPoint){String name=joinPoint.getSignature().getName();String args= Arrays.toString(joinPoint.getArgs());System.out.println(name+"方法的参数是:"+args);}@After("execution(public int com.test.Impl.CalImpl.*(..))")public void after(JoinPoint joinPoint){String name=joinPoint.getSignature().getName();System.out.println(name+"方法执行完毕");}@AfterReturning(value="execution(public int com.test.Impl.CalImpl.*(..))",returning = "result")public void afterReturn(JoinPoint joinPoint,Object result){String name=joinPoint.getSignature().getName();System.out.println(name+"方法的结果是"+result);}@AfterThrowing(value = "execution(public int com.test.Impl.CalImpl.*(..))",throwing = "exception")public void afterThrowing(JoinPoint joinPoint,Exception exception){String name=joinPoint.getSignature().getName();System.out.println(name+"方法抛出异常"+exception);}
}
原接口类和接口不变,实现类加@Component
import org.springframework.stereotype.Component;@Component
public class CalImpl implements Cal {@Overridepublic int add(int num1, int num2) {int result=num1+num2;return result;}@Overridepublic int sub(int num1, int num2) {int result=num1-num2;return result;}@Overridepublic int mul(int num1, int num2) {int result=num1*num2;return result;}@Overridepublic int div(int num1, int num2) {int result=num1/num2;return result;}
}
主类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");Cal cal=(Cal)applicationContext.getBean(Cal.class);cal.add(10,3);cal.sub(10,3);cal.mul(10,3);cal.div(10,3);cal.div(10,0);}
}