新闻资讯
Spring框架中的JDK与CGlib动态代理
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
得证!
回复列表