IOC: 제어 반전, 객체 생성 및 객체 간 호출 프로세스를 관리를 위해 Spring에 넘겨줍니다. IOC를 사용하는 목적은 결합을 줄이는 것입니다.
AOP: 관점 지향 프로그래밍, 런타임 중 사전 컴파일 및 동적 프록시를 통해 프로그램 기능의 통합된 유지 관리를 달성하는 기술입니다. AOP는 소프트웨어 개발의 핫스팟이자 Spring 프레임워크의 중요한 콘텐츠이자 함수형 프로그래밍의 파생 패러다임인 OOP의 연속입니다. AOP를 사용하면 비즈니스 로직의 다양한 부분을 분리하여 비즈니스 로직의 다양한 부분 간의 결합을 줄이고 프로그램의 재사용성을 향상시키며 개발 효율성을 높일 수 있습니다. AOP의 기본 구현은 동적 프록시를 기반으로 합니다(구현 방법은 인터페이스로 전환할 때 JDK 기본 동적 프록시를 사용하는 것입니다. 일반 방법으로 전환할 때는 cglib 동적 프록시를 사용합니다).
지속적인 비즈니스 확장과 함께:
(1) 로그 기능: 로그 코드가 수정되면 많은 수정이 필요합니다.
(2) 확인 기능: 여러 곳을 확인해야 하는 경우 여러 번 변경해야 합니다.
이때 문제를 해결하려면 동적 프록시를 사용해야 합니다. 동적 프록시를 구현하는 방법에는 두 가지가 있습니다.
[1] JDK 기본 동적 프록시: 인터페이스를 기반으로 완료해야 한다는 단점이 있습니다.
[2] cglib 동적 프록시: 사용할 수 없음 인터페이스
public interface MathService { //+ public Double add(double a,double b); //- public Double sub(double a,double b); //* public Double mul(double a,double b); /// public Double div(double a,double b); }
public class MathServiceImpl implements MathService{ @Override public Double add(double a, double b) { Double result=a+b; return result; } @Override public Double sub(double a, double b) { Double result=a-b; return result; } @Override public Double mul(double a, double b) { Double result=a*b; return result; } @Override public Double div(double a, double b) { Double result=a/b; return result; } }
public class ProxyFactory { //被代理对象 private Object target; public ProxyFactory(Object target) { this.target = target; } //获取代理对象 public Object getProxy(){ /** * ClassLoader loader, 被代理对象的类加载器 * Class<?>[] interfaces, 被代理对象实现的接口 * InvocationHandler h: 当代理对象执行被代理的方法时,会触发该对象中的invoke功能 */ ClassLoader loader=target.getClass().getClassLoader(); Class<?>[] interfaces=target.getClass().getInterfaces(); InvocationHandler h=new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //可以加上需要的非业务代码 //method.getName()获取方法名 // Arrays.asList(args)获取输入值 System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args)); //method:表示代理对象要代理的方法 //invoke:回调该函数 //args:方法需要的参数 Object result = method.invoke(target, args);//代理对象回调该方法 return result; } }; //先写此处方法,才可找到上述三个方法填写方式 Object o = Proxy.newProxyInstance(loader, interfaces, h); return o; } }
public class Test01 { public static void main(String[] args) { MathServiceImpl target=new MathServiceImpl(); ProxyFactory proxyFactory=new ProxyFactory(target); MathService proxy = (MathService) proxyFactory.getProxy(); Double add = proxy.add(15.0, 5.0); System.out.println(add); } }
public class MathServiceImpl{ public Double add(double a, double b) { Double result=a+b; return result; } public Double sub(double a, double b) { Double result=a-b; return result; } public Double mul(double a, double b) { Double result=a*b; return result; } public Double div(double a, double b) { Double result=a/b; return result; } }
참고:
(1) 소개 cglib jar 패키지.
cglib
cglib
3.2.5
(2) 프록시 클래스 팩토리 생성 및 MethodInterceptor 인터페이스 구현
public class ProxyFactory implements MethodInterceptor { private Object target; public ProxyFactory(Object target) { this.target = target; } //获取代理对象 public Object getProxy(){ Enhancer enhancer=new Enhancer(); //指定被代理对象的父类 enhancer.setSuperclass(target.getClass()); //指定回调类 enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } //当代理对象执行代理方法时触发的方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // System.out.println("before++++++++++++++++++++"); // Object result = method.invoke(target, args); //可以加上需要的非业务代码 //method.getName()获取方法名 // Arrays.asList(args)获取输入值 System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args)); //method:表示代理对象要代理的方法 //invoke:回调该函数 //args:方法需要的参数 Object result = method.invoke(target, args);//代理对象回调该方法 return result; } }
public class Test01 { public static void main(String[] args) { MathServiceImpl target=new MathServiceImpl(); ProxyFactory proxyFactory=new ProxyFactory(target); MathServiceImpl proxy = (MathServiceImpl) proxyFactory.getProxy(); Double add = proxy.add(1, 2); System.out.println(add); } }
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.15.RELEASE</version> </dependency>
<?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:context="http://www.springframework.org/schema/context" 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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--包扫描--> <context:component-scan base-package="com.qy151wd.proxy.proxy.aop"/> <!--开启aop注解--> <aop:aspectj-autoproxy/> </beans>
public interface MathService { public Double add(double a, double b); public Double sub(double a, double b); public Double mul(double a, double b); public Double div(double a, double b); }
@Service public class MathServiceImpl implements MathService { @Override public Double add(double a, double b) { Double result=a+b; return result; } @Override public Double sub(double a, double b) { Double result=a-b; return result; } @Override public Double mul(double a, double b) { Double result=a*b; return result; } @Override public Double div(double a, double b) { Double result=a/b; return result; } }
@Service //若是使用@component也可以 @Aspect //表示该类为切面类 public class LogAspect { //任意返回类型 aop包下的所有类都有切面日志 使用通配符 //第一个*:修饰符和返回值类型 //第二个*:所有类 //第三个*:所有方法 @Before("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))") public void before(){ System.out.println("方法执行前的日志"); } @After("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))") //总会被执行,不管有没有异常 public void after(){ System.out.println("方法执行后的日志"); } @AfterReturning("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//只有碰到return后才会执行 public void afterReturning(){ System.out.println("碰到return后执行"); } @AfterThrowing("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//异常通知 public void afterThrowing(){ System.out.println("出现异常了"); } }
public class Test01 { public static void main(String[] args) { //从spring容器中获取 ApplicationContext app=new ClassPathXmlApplicationContext("spring.xml"); MathService mathService = (MathService) app.getBean("mathServiceImpl"); Double add = mathService.add(10, 5); System.out.println(add); } }
위 내용은 Java AOP 동적 프록시란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!