[Spring] agency model with jdk dynamic proxy in Spring and dynamic proxies cglib

Proxy mode:

Define a proxy mode : mode proxy (Proxy Pattern) is a programming design pattern. Providing a proxy to control access to the object to other objects. In some cases, an object is not suitable or not directly refer to another object, the proxy object can play the role of intermediary between the client and the target audience.
Proxy mode of composition :

  • 1, abstract role : business methods implemented through an interface or abstract class declaration real role.
  • 2, the real role : to achieve abstract role, define business logic real role to be achieved, calls for acting role.
  • 3, agent roles : to achieve abstract role, the role of agents is real, abstract methods to achieve real business logic methods by role, and can attach their own operations.

Agent Category :

  • Static proxy : already determine the true class agent class and its agents before the program run. For example, when writing a program, specify an interface A. A Class B implements the interface to improve its logic code. A class C also implements the interface, but does not own the logic code, instead of referring to the logic code class B, class C may also do some other logic operations on the basis of the code which references a class B. At this point, it is called Class C Class B is static agent.
  • Dynamic proxy : proxy class is determined only when the program is running, the dynamic proxy There are two common implementations: jdk dynamic proxy and cglib dynamic proxy.

Spring AOP implied dynamic proxy:

A: Spring AOP use jdk dynamic proxy:

Jdk want to use the agent in the spring, the following conditions are required:
1. definition of an interface , for example:

package cn.jingpengchong.math.service;

public interface IMathService {
	int div(int a, int b);
}

2, the definition of a class that implements the interface , for example:

package cn.jingpengchong.math.service;

import org.springframework.stereotype.Service;
//使用spring自动实例化对象,需添加能够被扫描到的特定注解
@Service
public class MathService implements IMathService {
	public int div(int a, int b) {
		System.out.println("日志:The div method begins");
		return a/b;
	}
}

3, following configurations spring xml configuration file :

<!--假如不写proxy-target-class属性则默认是false-->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

4, the definition section, and the starting point must be matched to the real class enhancement processing , for example:

package cn.jingpengchong.math.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//该注解指定该类为切面类
@Aspect
//使用spring自动实例化对象,需添加能够被扫描到的特定注解
@Component
public class MethodAOP {
	
	//前置处理,表达式要与真实类的某个方法匹配,否则无法生成代理类
	@Before("execution(public int cn.jingpengchong.math.service.MathService.*(..))")
	public void before() {
	//此处可以添加附加操作
	}
}

5, is obtained by the interface proxy class object instance corresponding to the class Class , for example:

package cn.jingpengchong.math.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.math.service.IMathService;
import cn.jingpengchong.math.service.MathService;

public class Test {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		//此处不能通过真实类对应的Class类的实例化对象获得代理类
		IMathService mathService = applicationContext.getBean(IMathService.class);
		System.out.println("mathService的类是:");
		System.out.println(mathService.getClass());
		System.out.println("mathService的父类是:");
		System.out.println(mathService.getClass().getSuperclass());
		Class<?>[] interfaces = mathService.getClass().getInterfaces();
		System.out.println("mathService的类实现的接口有:");
		for (Class<?> c : interfaces) {
			System.out.println(c);
		}
		applicationContext.close();
	}
}

Results are as follows, the following way may be observed Class Agent class parent class interface and implementation :
Here Insert Picture Description
if not made to the configuration of step 3, the results are as follows:
Here Insert Picture Description
If the section does not step 4 expression with a real class the method of any match, the results are as follows:
Here Insert Picture Description
If the object is instantiated in step 5 with the real class corresponding to the class class to obtain the proxy class, the results are as follows:
Here Insert Picture Description

Two, Spring AOP cglib use dynamic proxies:

Spring is used with similar cglib jdk dynamic proxy agent, except that:
1, the aop spring xml configuration file: proxy-target-class attribute value to aspectj-autoproxy tag to true;
2, either through the interface examples of the corresponding object class class obtained proxy class, the proxy class may also be obtained by a corresponding real object class instance of class class.

  • The results obtained in two ways proxy class is the same:
    Here Insert Picture Description

Three, jdk dynamic proxy and proxy cglib dynamic difference:

1, jdk dynamic proxy-based interface, while the real cglib dynamic proxy class implements based;
2, the JDK dynamic proxy indirect implement the interface, there is no inheritance relationship with the real class, and cglib dynamic agent directly inherited real class.

Spring's transaction management automatic dynamic proxies:

In addition, we found that a dynamic AOP proxy there is, in fact, in the spring of transaction management also uses dynamic proxy, Spring will be added @Transactional annotation class to create a proxy class, even though we did not in the Spring xml configuration file configuration aop: aspectj-autoproxy tag. For example, in the following example:

package cn.jingpengchong.car.service;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.jingpengchong.coupon.service.ICouponService;

@Service
public class CarService implements ICarService {

	@Autowired
	private ICouponService couponService;

	//购物车购买
	@Transactional
	@Override
	public boolean batch(String userId,Map<String,Integer> commodities) {
		Set<Entry<String, Integer>> set = commodities.entrySet();
		for (Entry<String, Integer> commodity : set) {
			String bookId = commodity.getKey();
			int count = commodity.getValue();
			System.out.println(bookId+","+count);
			couponService.insert(userId,bookId, count);
		}
		return true;
	}
}

And in the spring xml file is also not configured aop: aspectj-autoproxy tag, but when we write a test class as follows:

package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.coupon.service.ICouponService;

public class Test01 {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		ICouponService couponService = applicationContext.getBean(ICouponService.class);
		System.out.println("couponService的类是:");
		System.out.println(couponService.getClass());
		System.out.println("couponService的父类是:");
		System.out.println(couponService.getClass().getSuperclass());
		Class<?>[] interfaces = couponService.getClass().getInterfaces();
		System.out.println("mathService的类实现的接口有:");
		for (Class<?> c : interfaces) {
			System.out.println(c);
		}
		applicationContext.close();
	}
}

The result was found using a dynamic proxy, the proxy class to observe the class name we can clearly know that this is a jdk dynamic proxy because of its iconic words "Proxy":
Here Insert Picture Description

Published 128 original articles · won praise 17 · views 2724

Guess you like

Origin blog.csdn.net/qq_43705275/article/details/104245370