spring AOP 원리: 1. AOP는 측면 지향이며 객체 지향 프로그래밍 OOP를 개선하기 위해 프로그램 구조를 고려하는 또 다른 관점을 제공하는 프로그래밍 패러다임입니다. 2. AOP는 개발자에게 교차 편집 문제를 설명하는 방법을 제공합니다. 메커니즘을 사용하여 객체 지향 소프트웨어 시스템에 교차 관심 사항을 자동으로 엮을 수 있습니다.
spring AOP 원리:
AOP(Aspect-Oriented)는 객체 지향 프로그래밍(OOP)을 개선하기 위해 프로그램 구조를 고려하는 또 다른 관점을 제공하는 프로그래밍 패러다임입니다.
AOP는 개발자에게 교차 관심사를 설명하는 메커니즘을 제공하고 교차 관심사를 객체 지향 소프트웨어 시스템에 자동으로 엮어 교차 관심사의 모듈화를 달성할 수 있습니다.
AOP는 비즈니스와 관련이 없지만 트랜잭션 처리, 로그 관리, 권한 제어 등과 같이 비즈니스 모듈에서 일반적으로 호출되는 논리나 책임을 캡슐화하여 시스템 및 모듈 간의 결합을 통해 향후 운용성과 유지 관리성을 용이하게 합니다.
AOP 사용의 이점
모듈 결합 감소
시스템 확장이 용이함
코드 재사용성 향상
AOP의 기본 개념
JoinPoint: 교차점 연결 지점은 클래스 초기화, 메서드 호출, 필드 호출 또는 예외 처리 등에 삽입되어야 합니다. Spring에서는 메서드 실행 연결 지점만 지원됩니다.
포인트컷: 관련 연결 지점의 집합입니다.
조언: 연결 지점에서 수행되는 동작은 진입점에서 선택한 연결 지점에서 AOP의 기존 동작을 확장하는 수단을 제공합니다. 강화 전(조언 전), 강화 후(조언 후), 서라운드 강화(조언 주변)를 포함합니다.
Aspect: 알림과 진입점의 조합입니다.
Weaving: Weaving은 AOP 프록시 객체를 생성하기 위해 대상 객체에 Aspect를 적용하는 프로세스입니다.
Proxy: 프록시를 통해 대상 개체에 측면을 적용합니다. AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시를 사용하여 구현할 수 있습니다.
대상: 초점으로 엮어야 하는 개체입니다. 즉, 프록시되는 개체입니다.
AOP를 구현하는 주요 디자인 패턴은 동적 프록시입니다.
Spring에는 두 가지 유형의 동적 프록시가 있습니다. 하나는 JDK 동적 프록시이고 다른 하나는 cglib 동적 프록시입니다.
JDK 동적 프록시 시뮬레이션
JDK 동적 프록시의 두 가지 핵심 인터페이스(클래스)는 InvocationHandler와 Proxy입니다. 참고: 프록시 인터페이스만 사용할 수 있습니다.
public class TimeHandler implements InvocationHandler { // 目标对象 private Object targetObject; public TimeHandler(Object targetObject){ this.targetObject = targetObject; } @Override //关联的这个实现类的方法被调用时将被执行 /*InvocationHandler接口的方法,proxy表示代理,method表示原对象被调用的方法, args表示方法的参数*/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret=null; try{ System.out.println("方法之前:"+System.currentTimeMillis()); //调用目标方法 ret=method.invoke(targetObject, args); System.out.println("方法之后:"+System.currentTimeMillis()); }catch(Exception e){ e.printStackTrace(); System.out.println("error"); throw e; } return ret; } }
TimeHandler 클래스는 InvocationHandler 인터페이스를 구현합니다. 3개의 매개변수가 있는 핵심 메서드 호출을 구현합니다. 첫 번째 매개변수는 생성된 프록시 클래스 인스턴스이고, 두 번째 매개변수는 대상 객체의 메서드, 세 번째 매개변수는 메서드의 매개변수 값 배열입니다.
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(ClassLoader loader,Class<?>[] clz,InvocationHandler handler){ return (T)Proxy.newProxyInstance(loader, clz, handler); } }
ProxyUtil 클래스는 단순히 Proxy.newProxyInstance() 메서드를 캡슐화합니다. 이 메서드에는 3개의 매개변수도 있습니다. 첫 번째 매개변수는 프록시 객체의 클래스 로더를 생성하고, 두 번째 매개변수는 대상 객체의 인터페이스 배열, 세 번째 매개변수는 InvocationHandler 인터페이스를 구현하는 클래스 인스턴스를 생성합니다.
public interface UserManager { public void addUser(String userId, String userName); } public class UserManagerImpl implements UserManager { @Override public void addUser(String userId, String userName) { System.out.println("addUser(id:"+userId+",name:"+userName+")"); } } public static void main(String[] args) { UserManager um=new UserManagerImpl(); LogHandler log =new LogHandler(um); um=ProxyUtil.proxyOne(um.getClass().getClassLoader(), um.getClass().getInterfaces(), log); TimeHandler time = new TimeHandler(um); um=ProxyUtil.proxyOne(um.getClass().getClassLoader(), um.getClass().getInterfaces(), time); um.addUser("1111", "张三"); }
시연을 위해 여기에 TimeHandler 코드와 동일한 LogHandler를 추가합니다.
CGLIB 동적 프록시 시뮬레이션
CGLIB 동적 프록시의 두 가지 핵심 인터페이스(클래스)는 MethodInterceptor와 Enhancer입니다. JDK 동적 프록시와 매우 유사하며 사용법도 비슷합니다. 그러나 CGLIB는 클래스와 인터페이스를 프록시할 수 있습니다. 참고: 최종 클래스는 프록시될 수 없습니다.
public class TimeInterceptor implements MethodInterceptor { private Object target; public TimeInterceptor(Object target) { this.target = target; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy invocation) throws Throwable { System.out.println("方法之前:"+System.currentTimeMillis()); Object ret = invocation.invoke(target, args); System.out.println("方法之后:"+System.currentTimeMillis()); return ret; } }
intercept 메소드에는 4개의 매개변수가 있습니다. 1. 생성된 프록시 클래스 인스턴스. 2. 프록시 객체의 메소드에 의해 참조됩니다. 3. 메소드 매개변수 값의 배열. 4. 메서드에 대한 프록시 클래스의 프록시 참조입니다.
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(Class<?> clz,MethodInterceptor interceptor){ return (T)Enhancer.create(clz, interceptor); } }
Enhancer 클래스는 CGLib의 바이트코드 강화기입니다.
public class UserManage { public void addUser(String userId, String userName) { System.out.println("addUser(id:"+userId+",name:"+userName+")"); } } public static void main(String[] args) { UserManage um = new UserManage(); TimeInterceptor time = new TimeInterceptor(um); um = ProxyUtil.proxyOne(um.getClass(), time); um.addUser("111", "老王"); }
관련 무료 학습 권장사항: java 기본 튜토리얼
위 내용은 Spring AOP의 원리는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!