지향 프로그래밍 Aop--

정적 및 동적 에이전트 프록시

AOP 동적 에이전트의 기초

정적 에이전트

에이전트 모델 :

  1. 추상 역할 : 일반적으로 추상 클래스 또는 인터페이스를 사용
  2. 실제 역할 : 에이전트의 역할
  3. 역할 연기 : 에이전트의 실제 역할을, 일반적으로 몇 가지 부수적 인 작업을 할
  4. 고객 : 에이전트 역할을 사용하여 얻을하기 위해 뭔가를 할 것 에이전트 역할의 실제 역할과 고유의 것

코드 구현 :( 우리는 예를 들어, 아파트를 임대)

  1. 인터페이스 :

    //租房的接口:抽象
    public interface Rent {
        //租房
        void rent();
    }
  2. 실제 개체 :

    //房东的这个房子要出租
    public class Host implements Rent {//房东实现rent接口
        //出租
        public void rent(){
            System.out.println("host要出租房子");
        }
    
    }
  3. 객체의 생성 :

    package com.david.staticproxy;
    
    //中介,即代理
    public class Proxy implements Rent {//中介实现rent接口
        //房东
        private Host host;
        public void setHost(Host host) {
            this.host = host;
        }
        public void rent() {
            lookHouse();//看房方法
            host.rent();//租房子方法
            fare();//收费方法
        }
        private void lookHouse(){
            System.out.println("中介带你看房");
        }
        private void fare(){
            System.out.println("收取中介费");
        }
    }
  4. 테스트 :

    public class You {
        public static void main(String[] args) {
    
            Host host = new Host();
    
            Proxy proxy = new Proxy();
            proxy.setHost(host);
            proxy.rent();
    
        }
    }

정적 기관의 연습 기능 :

  1. 장점 :
    1. 더 순수 진정한 역할을 할 수 있습니다, 당신은 몇 가지 일반적인 것들에 초점을 맞출 필요가 없습니다;
    2. 사업의 부문 브로커에 의해 수행 공공 사업;
    3. 공공 서비스는 더 집중하고 편리 할 수 ​​있습니다, 확장하는 단계;
  2. 단점 :
    1. 우리의 진정한 역할은 매우 커질 경우, 프록시 클래스는 증가, 작업의 많은 양의, 개발 효율성이 낮습니다!

동적 프록시

때문에 낮은 정적 에이전트 개발 효율성에, 그래서 우리는 정적 에이전트에 대한 필요성의 모든 혜택을 가질 수 있기를 원하지만 그런 것들이 단점이 존재하지 않습니다.

연기 역할은 같은 동적 및 정적 에이전트하지만, 동적 프록시는 자동으로 생성됩니다.

  1. 동적 프록시는 두 개의 카테고리로 나누어 :

    1. 기반 인터페이스 : JDK

    2. 클래스 구현을 기반으로 : CGLIB

      오늘은 동적 프록시와 Javassist를 생성하기 위해 더 많이 사용된다

  2. 동적 프록시 관련 카테고리 :

    1. 프록시 인스턴스의 호출 핸들러에 의해 InvocationHandler입니다 * 구현 된 인터페이스
      1. '호출 프로세싱 프록시 인스턴스의 방법 및 결과를 리턴 (인수는 [] 개체 개체 프록시 방법 법)에 호출한다.
    2. 프록시 동적 프록시 클래스 및 인스턴스가 이러한 방법에 의해 생성되는 모든 동적 프록시 클래스의 수퍼 클래스를 작성하기위한 정적 방법을 제공한다.
      1. newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h) 지정된 인터페이스의 프록시 클래스의 인스턴스를 돌려줍니다 지정된 메소드 호출 핸들러에 할당 된 인터페이스를 호출
  3. 코드 구현 :

    1. 추상 역할

      package com.li.daili.dao;
      
      public interface Rent {
          void rent();
      }
    2. 실제 역할

      package com.li.daili.dao;
      
      public class Host implements Rent{
          public void rent() {
              System.out.println("房东要租房");
          }
      }
    3. 동적 프록시 인터페이스 객체를 생성

      package com.li.daili.dao;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      public class InvocationHandlerProxy implements InvocationHandler {
          private Rent rent;
      
          public void setRent(Rent rent) {
              this.rent = rent;
          }
      
          public Object getProxy(){
              return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
          }
      
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              lookHouse();
              Object result = method.invoke(rent, args);
              takeMoney();
              return result;
          }
      
          private void takeMoney() {
              System.out.println("收费");
          }
      
          private void lookHouse() {
              System.out.println("看房");
          }
      }
    4. 테스트

      package com.li.daili;
      
      import com.li.daili.dao.Host;
      import com.li.daili.dao.InvocationHandlerProxy;
      import com.li.daili.dao.Rent;
      
      public class TestDemo {
          public static void main(String[] args) {
              Host host = new Host();
              InvocationHandlerProxy ihp = new InvocationHandlerProxy();
              ihp.setRent(host);
              Rent proxy = (Rent) ihp.getProxy();
              proxy.rent();
          }
      }
  4. 동적 프록시 기능 :

    1. 더 순수 진정한 역할을 할 수 있습니다, 당신은 몇 가지 일반적인 것들에 초점을 맞출 필요가 없습니다;
    2. 사업의 부문 브로커에 의해 수행 공공 사업;
    3. 공공 서비스는 더 집중하고 편리 할 수 ​​있습니다, 확장하는 단계;
    4. 동적 프록시, 서비스 일반 프록시 클래스 프록시 에이전트 수있는 복수의 동적 클래스 프록시 인터페이스;


AOP

AOP 동적 에이전트의 기초

AOP는 OOP의 연속이 Aspect 지향적 인 프로그래밍을 의미 프로그래밍 약어를 지향이다. 사전 컴파일로서 동적 프록시 런 달성대한 소스 코드를 수정하지 않는 경우의 프로그램 동적 연합에 기능을 추가하는 기술. AOP가 실제로 GoF의 디자인 패턴의 연속이다, 디자인 패턴은 발신자와 수신자 사이에 추진되는 디커플링 , AOP는이 목적을 구현 한 것입니다 말할 수 있습니다.

우리가 같은 일부 비 사업을하고 있습니다 : 로그, 트랜잭션, 보안 및 기타 비즈니스가 (즉, 비즈니스 클래스 비즈니스 클래스 이러한 비 가로) 코드로 작성되지만,이 코드는 종종 반복적 인 코드되어 줄 것이다 이러한 비즈니스 요구 사항과 시스템 요구 사항의 실현에 유지 보수 절차의 불편, AOP는 별도로 않습니다. 이를 해결하는 방법도 알려져있다 프록시 메커니즘 .

1. AOP 달성 springAPI

  1. 비즈니스 클래스의 준비

    1. 인터페이스

      package com.david.aop.service;
      
      public interface UserService {
          void add();
          void delete();
          void update();
          void query();
      }
    2. 구현 클래스

      package com.david.aop.service;
      
      public class UserServiceImpl implements UserService{
          public void add() {
              System.out.println("添加一个用户");
          }
      
          public void delete() {
              System.out.println("删除一个用户");
          }
      
          public void update() {
              System.out.println("更新一个用户");
          }
      
          public void query() {
              System.out.println("查询一个用户");
          }
      }
      
  2. 증가 클래스는 사용자 지정 로그를 구현

    package com.david.aop.log;
    
    import org.springframework.aop.MethodBeforeAdvice;
    
    import java.lang.reflect.Method;
    
    public class Log implements MethodBeforeAdvice {
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");
        }
    }
    package com.david.aop.log;
    
    import org.springframework.aop.AfterReturningAdvice;
    
    import java.lang.reflect.Method;
    
    public class AfterLog implements AfterReturningAdvice {
        public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
            System.out.println("执行了"+target.getClass().getName() +"的"+method.getName()+"方法" +"返回值"+returnValue);
        }
    }
  3. 봄 코어 구성 파일 applaction-config.xml에 쓰기

    <?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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.david.aop.service.UserServiceImpl"/>
    
        <bean id="log" class="com.david.aop.log.Log"/>
        <bean id="afterLog" class="com.david.aop.log.AfterLog"/>
    
    
    
        <aop:config>
            <aop:pointcut id="pointcut" expression="execution(* com.david.aop.service.UserServiceImpl.*(..))"/>
            <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
            <aop:advisor  advice-ref="afterLog" pointcut-ref="pointcut"/>
        </aop:config>
    </beans>
  4. 테스트 카테고리

    package com.david.service;
    
    import com.david.aop.service.UserService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SpringAopTest {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("application-config.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
            userService.update();
            userService.query();
            userService.delete();
        }
    }
    

    직물 패킷 AOP의 수입을 참고

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>springstudy</artifactId>
            <groupId>com.li</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>springstudy03</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
    </project>

    결과 :

    com.david.aop.service.UserServiceImpl的add被执行了
    添加一个用户
    执行了com.david.aop.service.UserServiceImpl的add方法返回值null
    com.david.aop.service.UserServiceImpl的update被执行了
    更新一个用户
    执行了com.david.aop.service.UserServiceImpl的update方法返回值null
    com.david.aop.service.UserServiceImpl的query被执行了
    查询一个用户
    执行了com.david.aop.service.UserServiceImpl的query方法返回值null
    com.david.aop.service.UserServiceImpl的delete被执行了
    删除一个用户
    执行了com.david.aop.service.UserServiceImpl的delete方法返回值null

AOP 아이디어가 중요하다 : 수평 프로그램 (소스 코드 변경, 기능을 추가). AOP 또는 에이전트의 동적 인 특성은, 코드에서 디커플링의 역할을

AOP의 구현 2. 사용자 정의 클래스

사용 springAPI AOP를 달성하기 위해 상대적으로 쉽게

  1. 실제 개체 추천하고 전

  2. AOP 사용자 정의 클래스를 향상 : 소위 섹션을

    package com.david.aop.diy;
    
    public class Diy {
        public void before(){
            System.out.println("===========before============");
        }
        public void after(){
            System.out.println("===========after============");
        }
    }
  3. AOP 강화 beans.xml 환경을 사용하여 빈을 주입

    <?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: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/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
        <bean id="userService" class="com.david.aop.service.UserServiceImpl"/>
        <bean id="diy" class="com.david.aop.diy.Diy"/>
        <aop:config>
            <aop:aspect ref="diy">
                <aop:pointcut id="diyPointcut" expression="execution(* com.david.aop.service.UserServiceImpl.*(..))"/>
                <aop:before method="before" pointcut-ref="diyPointcut"/>
                <aop:after method="after" pointcut-ref="diyPointcut"/>
            </aop:aspect>
        </aop:config>
    </beans>
  4. 테스트 카테고리

    package com.david.service;
    
    import com.david.aop.service.UserService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SpringAopTest {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
            userService.update();
            userService.query();
            userService.delete();
        }
    }
  5. 결과 :

    ===========before============
    添加一个用户
    ===========after============
    ===========before============
    更新一个用户
    ===========after============
    ===========before============
    查询一个用户
    ===========after============
    ===========before============
    删除一个用户
    ===========after============

AOP를 달성하기 위해 3. 주석

@ 화면 @ 전에 @ @ 약, 후

  1. 변경 대상

  2. 강화 된 쓰기 수업, 쓰기 노트

    1. 수업 노트를 절단 할 필요가 : 점을 참고
    2. 상기 방법은 시작점 강화한다는 것이다
  3. 카테고리 :

    package com.david.aop.anno;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    
    @Aspect
    public class Anno {
    
        @Before("execution(* com.david.aop.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("===========方法执行前==========");
        }
    
        @After("execution(* com.david.aop.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("==========执行方法后===========");
        }
    
        @Around("execution(* com.david.aop.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("环绕前");
            System.out.println("签名"+joinPoint.getSignature());
            Object proceed = joinPoint.proceed();
            System.out.println("环绕后");
            System.out.println(proceed);
        }
    }
  4. 프로필 : anno.xml

    <?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: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/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
        <bean id="userService" class="com.david.aop.service.UserServiceImpl"/>
        <bean id="anno" class="com.david.aop.anno.Anno"/>
        <aop:aspectj-autoproxy/><!--自动代理-->
    </beans>
  5. 시험 종류 :

    package com.david.service;
    
    import com.david.aop.service.UserService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SpringAopTest {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("anno.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
            userService.update();
            userService.query();
            userService.delete();
        }
    }

AOP 요약

  1. 자연은 동적 프록시

  2. 패킷에 필요한 패키지 AOP로 짠합니다 : aspectjweaver

  3. 상처를 그리워하지 않도록주의 재생의 과정에서 코드

  4. AOP의를 달성하는 세 가지 방법

      • AOP를 달성하기 위해 SpringAPI를 사용하여
      • AOP를 구현하는 사용자 정의 클래스를 사용하여
      • AOP를 달성하기 위해 주석을 사용하여

추천

출처www.cnblogs.com/a-xia/p/11400968.html