SpringAOP Principle Analysis

table of Contents

Spring Core Knowledge

SpringAOP principle

AOP programming

What is AOP programming

AOP principle underlying implementation

Programming using AOP


 

Spring Core Knowledge

Spring is an open source framework Spring is a lightweight rise in 2003 Java development framework, part of the philosophy set forth by the Rod Johnson in his book Expert One-On-One J2EE Development and Design and prototypes derived. It is designed to address the complexity of enterprise application development created. One of the main advantages of the framework is its layered architecture, layered architecture allows the user to select which components to use, as well as J2EE application development provides an integrated framework. Spring uses basic JavaBean to do things previously only possible done by EJB. However, Spring's use is not limited to server-side development. Any Java application can benefit from the simplicity, testability and loose coupling from the perspective of Spring. The core is the Spring Inversion of Control (IoC) and the facing section (AOP). Briefly, Spring is a layered JavaSE / EEfull-stack (stop) lightweight open source framework.

Why Spring is a lightweight open source framework stop it? EE developers can be divided into three-tier architecture for JavaEE of the three-tier structure, with each layer Spring offers a different solution techniques.

• WEB layer: SpringMVC

• Business layer: Spring's IoC

• persistence layer: Spring of JDBCTemplate (Spring's JDBC templates, ORM templates for integrating other persistence frameworks)

From the brief description above, we need to know the core Spring has two parts:

• IoC: Inversion of Control.

For example, before the operation, say there is a class, we want to call the class inside the method (not a static method), it is necessary to create object classes, use the object to call methods. For Spring, Spring's creation of objects, which is not implemented in the code, but to the Spring configuration to achieve.

AOP: Aspect Oriented Programming.

SpringAOP principle

AOP programming

 

What is AOP programming

AOP: Aspect Oriented Programming Aspect Oriented Programming. Aspect Oriented Programming (also called aspect-oriented): Aspect Oriented Programming (AOP) , is a hot spot in software development. AOP can use to isolate each part of the business logic such that the business logic to reduce the degree of coupling between the parts, improve the reusability of the program, while improving efficiency of development. AOP is a continuation of OOP is (Aspect Oriented Programming) acronym, meaning that cut faces (aspect) programming. The main functions are: logging, performance statistics, security control, transaction processing, exception handling , and so on. The main intention is: logging, performance statistics, security control, transaction processing, exception handling code is divided from the business logic code, by separating these actions, we hope they can be independent non-methodological guidance business logic in, and then change the behavior of the time does not affect the business logic code.

 

  One technique for dynamically unified program to add functionality without modifying the source code can be achieved by pre-compiled dynamic proxy mode and runtime. AOP is actually a continuation of the GoF design patterns, design patterns tireless pursuit of decoupling between the caller and the callee, AOP can say this is an implementation of this objective.

Suppose the application think of a three-dimensional structure, then, of OOP razor is a longitudinal cut system, the system is divided into a number of modules (such as: a user module, articles module, etc.), and the AOP razor transverse cut system, extraction of each module some may be repeated operations (such as: permission checks, logging, etc.). Thus, AOP is an effective complement of OOP.

Note: AOP is not a technology, actually programming ideas. Those who meet the AOP thinking technology, can be seen as to achieve AOP.

 

AOP , Aspect Oriented Programming Object Programming

Function: Let the concerns of code separate from the business code!

focus point

Concern, duplicate code is called concern;

section

Class focus formation, called section (class)!

Oriented Programming, refers to the many functions are repeated extraction code, when running on another network service Dynamic implant "class code section."

Entry point

Execution target object method, DYNAMIC IMPLANT section codes.

By pointcut expression, which specify which classes intercept method; implant cut to the specified class class code at run time.

AOP principle underlying implementation

Proxy design pattern

What is a proxy mode

Methods proxy access control objects through, you can access details of an object, in this post-call processing method, or call processing. Both (AOP micro realize), AOP Aspect Oriented Programming core technology.

 

Proxy mode scenario

SpringAOP, things principle, log printing, access control, remote call, the security agent may conceal the true role

Acting classification

Static agents (statically defined proxy class)

Dynamic proxy (proxy class dynamically generated)

Jdk comes with dynamic proxies

Cglib, javaassist (bytecode manipulation library)

Static agents

What is a static agent

Created by the programmer or tool to generate a proxy class source code, and then compile the proxy class. The so-called static before the program is run on an existing relationship byte code file, the proxy class and delegate class proxy class before running is determined.

 

Static agent code

public interface IUserDao {
    void save();
}
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("已经保存数据...");
    }
}
代理类
public class UserDaoProxy implements IUserDao {
    private IUserDao target;
    public UserDaoProxy(IUserDao iuserDao) {
        this.target = iuserDao;
    }
    public void save() {
        System.out.println("开启事物...");
        target.save();
        System.out.println("关闭事物...");
    }
}

Dynamic Proxy

 

 

What is the dynamic agent

1. proxy object, do not need to implement the interface

2. generate proxy objects, using the JDK API, build dynamic proxy object in memory (requires us to specify the type of interface to create a proxy object / target object implementation)

3. Dynamic Agent also known as: JDK agent, interface agent

JDK dynamic proxies

1) Principle: The class loader is created and proxy class interfaces (the proxy class is an implementation class interface, so the interface must be used for the interface generation agent, located at java.lang.reflect package)

2) ways:

  1. InvocationHandler by implementing the interface to create your own call processor IvocationHandler handler = new InvocationHandlerImpl (...);

  2. Create a dynamic proxy class Class clazz ClassLoader by specifying a set of interface objects and for the Proxy class = Proxy.getProxyClass (classLoader, new Class [] {...});

  3. Obtaining dynamic proxy class constructor by reflection, which parameter type is a call processor interface type Constructor constructor = clazz.getConstructor (new Class [] {InvocationHandler.class});

  4. By creating a proxy class instance constructor calls this case need to be passed as a parameter handler object Interface Proxy = (Interface) constructor.newInstance (new Object [] (handler));

Drawback: jdk dynamic proxy, must be oriented interface to the target business class must implement the interface

// 每次生成动态代理类对象时,实现了InvocationHandler接口的调用处理器对象 
public class InvocationHandlerImpl implements InvocationHandler {
    private Object target;// 这其实业务实现类对象,用来调用具体的业务方法
    // 通过构造函数传入目标对象
    public InvocationHandlerImpl(Object target) {
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("调用开始处理");
        result = method.invoke(target, args);
        System.out.println("调用结束处理");
        return result;
    }
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // 被代理对象
        IUserDao userDao = new UserDao();
        InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);
        ClassLoader loader = userDao.getClass().getClassLoader();
        Class<?>[] interfaces = userDao.getClass().getInterfaces();
        // 主要装载器、一组接口及调用处理动态代理实例
        IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
        newProxyInstance.save();
    }
}

CGLIB dynamic proxy

Principle: asm using open source packages, class files proxy object classes loaded in, processed by modifying a subclass bytecode.

What is the dynamic proxy CGLIB

Use cglib [Code Generation Library] dynamic agent, does not require the delegate class must implement the interface, using the underlying framework asm generated bytecode generated proxy class bytecode

CGLIB dynamic proxy relevant code

public class CglibProxy implements MethodInterceptor {
    private Object targetObject;
    // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
    public Object getInstance(Object target) {
        // 设置需要创建子类的类
        this.targetObject = target;
        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("开启事物");
        Object result = proxy.invoke(targetObject, args);
        System.out.println("关闭事物");
        // 返回代理对象
        return result;
    }
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());
        userDao.save();
    }
}

Dynamic Proxy Dynamic difference between JDK CGLIB

java dynamic proxy using reflection to generate an anonymous proxy class that implements the interface call InvokeHandler before calling a specific method to process.

The dynamic proxy cglib asm using open source packages, class files proxy object classes loaded in, processed by modifying a subclass bytecode.

In Spring.

1, if the target object implements the interface, will use the default JDK dynamic proxy AOP implementation case

2, if the target object implements the interface, you can force the use of CGLIB achieve AOP

3, if the target object does not implement the interfaces must be used CGLIB library, spring will automatically switch between JDK dynamic proxies and CGLIB

JDK dynamic proxy class that implements the interface can only build agent, and not for the class. CGLIB agent is achieved for the class, the main class is specified to generate a sub-class, wherein the method of covering. Because it is inherited, so the class or method is best not to be declared as final, final can block inheritance, and polymorphism.

 

Programming using AOP

 

Notes version implements AOP

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>  开启事物注解权限
@Aspect                         指定一个类为切面类       
@Pointcut("execution(* com.service.UserService.add(..))")  指定切入点表达式
@Before("pointCut_()")              前置通知: 目标方法之前执行
@After("pointCut_()")               后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()")       返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()")           异常通知:  出现异常时候执行
@Around("pointCut_()")              环绕通知: 环绕目标方法执行
@Component
@Aspect
public class AopLog {
    // 前置通知
    @Before("execution(* com.service.UserService.add(..))")
    public void begin() {
        System.out.println("前置通知");
    }
    // 后置通知
    @After("execution(* com.service.UserService.add(..))")
    public void commit() {
        System.out.println("后置通知");
    }
    // 运行通知
    @AfterReturning("execution(* com.service.UserService.add(..))")
    public void returning() {
        System.out.println("运行通知");
    }
    // 异常通知
    @AfterThrowing("execution(* com.service.UserService.add(..))")
    public void afterThrowing() {
        System.out.println("异常通知");
    }
    // 环绕通知
    @Around("execution(* com.service.UserService.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知开始");
        proceedingJoinPoint.proceed();
        System.out.println("环绕通知结束");
    }
}

 

XML way to achieve AOP

Xml achieve aop programming:
    1) the introduction of the jar file [aop related jar, 4 Ge]
    2) the introduction of aop namespace
    3) aop configuration
        * Configuration aspect class (class code executed repeatedly formed)
        * Aop configuration
            After what methods interception / interception methods to notify the application of the code
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    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
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- dao 实例 -->
    <bean id="userService" class="com.service.UserService"></bean>
    <!-- 切面类 -->
    <bean id="aop" class="com.aop2.AopLog2"></bean>
    <!-- Aop配置 -->
    <aop:config>
        <!-- 定义一个切入点表达式: 拦截哪些方法 -->
        <aop:pointcut expression="execution(* com.service.UserService.*(..))"
            id="pt" />
        <!-- 切面 -->
        <aop:aspect ref="aop">
            <!-- 环绕通知 -->
            <aop:around method="around" pointcut-ref="pt" />
            <!-- 前置通知: 在目标方法调用前执行 -->
            <aop:before method="begin" pointcut-ref="pt" />
            <!-- 后置通知: -->
            <aop:after method="after" pointcut-ref="pt" />
            <!-- 返回后通知 -->
            <aop:after-returning method="afterReturning"
                pointcut-ref="pt" />
            <!-- 异常通知 -->
            <aop:after-throwing method="afterThrowing"
                pointcut-ref="pt" />
        </aop:aspect>
    </aop:config>
</beans>


public class AopLog2 {
    // 前置通知
    public void begin() {
        System.out.println("前置通知");
    }
    //
    // 后置通知
    public void commit() {
        System.out.println("后置通知");
    }
    // 运行通知
    public void returning() {
        System.out.println("运行通知");
    }
    // 异常通知
    public void afterThrowing() {
        System.out.println("异常通知");
    }
    // 环绕通知
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知开始");
        proceedingJoinPoint.proceed();
        System.out.println("环绕通知结束");
    }
}

 

 

 

Guess you like

Origin blog.csdn.net/weixin_40160543/article/details/92010760