新闻资讯

新闻资讯 通知公告

Spring框架中的JDK与CGlib动态代理

编辑:016     时间:2020-02-12

CGlib:可以是接口也可以是类

这里讨论的是test类中(是用接口还是目标类)

IMathService mathService = applicationContext.getBean(MathService.class);
test类中源码:

package com.jd.test;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.jd.math.IMathService;
import com.jd.math.MathService;
 
public class Test {
 
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		//true的时候是根据目标类来创建,false是根据接口来创建的,只能通过接口。
		IMathService mathService = applicationContext.getBean(MathService.class);
		System.out.println(mathService.getClass());
		applicationContext.close();
	}
}复制代码

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: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-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
 
  <context:component-scan base-package="com.jd"></context:component-scan>
  <!-- true基于目标类来创建 false是基于接口 -->
  <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>复制代码

这里在xml中;proxy-target-class="true" true的时候是根据目标类来创建,false是根据接口来创建的,只能通过接口


CGlib动态代理所产生的代理类是目标子类
JDK动态代理产生的代理类与目标的继承关系,其代理类是目标类所实现的接口的实现类

CGlib测试:xml中改为true

test类源码:

package com.jd.test;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.jd.math.IMathService;
import com.jd.math.MathService;
 
public class Test {
 
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		//true的时候是根据目标类来创建,false是根据接口来创建的,只能通过接口。jdk只能用接口
		//CGlib3.2开始自身支持CGlib
		IMathService mathService = applicationContext.getBean(MathService.class);
		//CGlib动态代理所产生的代理类是目标子类
		//JDK动态代理产生的代理类与目标的继承关系,其代理类是目标类所实现的接口的实现类
		System.out.println(mathService.getClass().getSuperclass());
		Class clazz = mathService.getClass();
		Class [] array = clazz.getInterfaces(); for(Class c:array) {
			System.out.println(c.getName());
		}
		applicationContext.close();
	}
}复制代码

运行结果:
class com.jd.math.MathService
org.springframework.aop.SpringProxy

org.springframework.aop.framework.Advised
org.springframework.cglib.proxy.Factory

JDK测试:xml中改为false

test类中

这里为IMathService。

运行结果:

class java.lang.reflect.Proxy
com.jd.math.IMathService

org.springframework.aop.SpringProxy

org.springframework.aop.framework.Advised

org.springframework.core.DecoratingProxy

事务中这两种讨论:CGlib

test源码:

package com.jd.test;
 
import java.util.HashMap;
import java.util.Map;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.jd.car.CarService;
import com.jd.car.ICarService;
import com.jd.coupon.service.CouponService;
import com.jd.coupon.service.ICouponService;
 
public class Test {
 
	/*public static void main(String[] args) {
		ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
		
		//立即购买
		ICouponService couponService = application.getBean(ICouponService.class);
		System.out.println(couponService.getClass().getName());
		
	//	String userId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
	//	String bookId = "8" ;
		//String bookId = "445" ;
		//库存有10本 他一次买了5本
	//	int count=7; if(couponService.insert(userId, bookId, count)) {
			
			System.out.println("OK");
		}
		
		//购物车购买
		ICarService carService = application.getBean(ICarService.class);
		String userId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
		Map<String,Integer> commodities = new HashMap<String,Integer>();
		//买两本书
		commodities.put("a2f39533-659f-42ca-af91-c688a83f6e49",1);
		commodities.put("4c37672a-653c-4cc8-9ab5-ee0c614c7425",1);
		carService.batch(userId, commodities);
		application.close();
	}*/
	
	public static void main(String[] args) {
		//一个类中的方法被@Transctional注解修饰,则Spring自动为该类创建代理类及代理对象   
		ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
		ICarService carService = application.getBean(CarService.class);
		System.out.println(carService.getClass().getName());
		application.close();
	}
}复制代码

test类中:ICarService carService = application.getBean(CarService.class);

这里为CarService.class

配置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:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
 
<!-- 创建IOC容器的时候就会扫描com.jd包下所有的类 -->
<context:component-scan base-package="com.jd"></context:component-scan>
 
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" p:password="123456" p:username="root">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/test"></property>
</bean>
  
<!-- 对JDBC进行配置    因为是引用类型所以用p:dataSource-ref=""-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"></bean>
 
<!-- 配置数据源事务管理器-->
<bean id="transactionManeger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
</bean>
 
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
 
</beans>复制代码

这里:<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

为true时

true的时候是根据目标类来创建,false是根据接口来创建的,只能通过接口

运行结果:

com.jd.car.CarService

EnhancerBySpringCGLIB

40b982ec

JDK代理:

test类中改为:

ICarService carService = application.getBean(ICarService.class);
xml中改为:

<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

运行结果:
com.sun.proxy.$Proxy11
得证!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐