Aop-- Oriented Programming

Static and dynamic agent Proxy

aop underlying dynamic agent

Static agents

Agent Model:

  1. Abstract role: generally use an abstract class or interface
  2. Real role: the role of agents
  3. Acting roles: the real role of the agent, usually do some ancillary operations
  4. Customer: Using the Agent role do something in order to get what the real role of the agent role and the unique thing

Code implementation :( We rent an apartment, for example)

  1. interface:

    //租房的接口:抽象
    public interface Rent {
        //租房
        void rent();
    }
  2. The real object:

    //房东的这个房子要出租
    public class Host implements Rent {//房东实现rent接口
        //出租
        public void rent(){
            System.out.println("host要出租房子");
        }
    
    }
  3. The generation of objects:

    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. test:

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

Static agency practice features:

  1. benefit:
    1. Can make a real role more pure, you do not have to focus on some common things;
    2. Public business done by brokers for the division of the business;
    3. Public service to be extended, it can be more focused and convenient;
  2. Disadvantages:
    1. If our true role has become very large, the proxy class will increase, and a large amount of work, development efficiency is low!

Dynamic Proxy

Due to the low static agent development efficiency, so we want to be able to have all the benefits of a need for a static agents, but such things do not exist shortcomings.

Acting roles are the same dynamic and static agent, but dynamic proxy is automatically generated.

  1. Dynamic proxies divided into two categories:

    1. Based interface: jdk

    2. Based on class implementation: cglib

      Today is used more to generate dynamic proxy Javassist

  2. Dynamic proxy-related categories:

    1. InvocationHandler by the invocation handler of a proxy instance * Implemented Interfaces
      1. invoke (Object proxy, Method method, Object [] args) `method of call processing proxy instance and returns the result.
    2. Proxy provides static methods for creating dynamic proxy classes and instances, all dynamic proxy class superclass it is created by these methods.
      1. newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h) Returns the specified interface proxy class instance, call the interface assigned to the specified method invocation handler
  3. Code:

    1. Abstract role

      package com.li.daili.dao;
      
      public interface Rent {
          void rent();
      }
    2. Real role

      package com.li.daili.dao;
      
      public class Host implements Rent{
          public void rent() {
              System.out.println("房东要租房");
          }
      }
    3. Dynamic proxy interface objects generated

      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. test

      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. Dynamic proxy features:

    1. Can make a real role more pure, you do not have to focus on some common things;
    2. Public business done by brokers for the division of the business;
    3. Public service to be extended, it can be more focused and convenient;
    4. A dynamic proxy, a generic proxy class of service, the proxy agent may a plurality dynamic classes, proxy interface;


AOP

aop underlying dynamic agent

AOP is a continuation of OOP is Aspect Oriented Programming acronym meaning Oriented Programming. By way of pre-compiled and dynamic proxy to achieve run- in does not modify the source code for a technology to add functionality to the program dynamic unity of the case. AOP is actually a continuation of the GoF design patterns, design patterns are pursued between the caller and the callee decoupling , AOP can say this is an implementation of this objective.

What we are doing some non-business, such as: logs, transactions, security and other business will be written in the code (That is, these non-transverse to the business class business class), but these codes are often repetitive code, will give maintenance procedures inconvenience, AOP on the realization of these business needs and system requirements do separately. The way to solve this is also known as proxy mechanism .

1. springAPI achieve aop

  1. Preparation of business class

    1. interface

      package com.david.aop.service;
      
      public interface UserService {
          void add();
          void delete();
          void update();
          void query();
      }
    2. Implementation class

      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. Increase class implements custom log

    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. Write spring core configuration file 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. Test category

    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();
        }
    }
    

    Note that import of weaving packet 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>

    operation result:

    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 ideas are important: horizontal program (source code change, add functionality). Aop or dynamic nature of the agent, played a role in the decoupling in the code

2. custom class that implements the AOP

Use springAPI relatively easier to achieve aop

  1. Like real object and before

  2. Aop enhance a custom class: the so-called section

    package com.david.aop.diy;
    
    public class Diy {
        public void before(){
            System.out.println("===========before============");
        }
        public void after(){
            System.out.println("===========after============");
        }
    }
  3. Inject bean, using aop enhanced 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. Test category

    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. operation result:

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

3. Use annotations to achieve AOP

@Aspect、@before、@after、@Around

  1. Audience unchanged

  2. Enhanced writing class, writing notes

    1. Note the point: the need to cut the class notes
    2. The method is that the starting point to enhance
  3. class:

    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. Profile: 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. Test categories:

    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 summary

  1. Nature is dynamic proxy

  2. Required to a packet, to be woven into the package aop: aspectjweaver

  3. Code in the process of playing careful not to miss the cut

  4. Three ways to achieve the AOP

      • Use SpringAPI to achieve AOP
      • Use custom classes to implement AOP
      • Use annotations to achieve AOP

Guess you like

Origin www.cnblogs.com/a-xia/p/11400968.html