问题描述
网上的文章都说 <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>配置了这句话的话就会强制使用cglib代理,如果proxy-target-class改成"false"的话就会先使用jdk动态代理如果不是接口来实现的话再使用cglib代理,但是我实验的时候如果proxy-target-class改成false的话永远是使用jdk动态代理啊,我也加了cglib的jar包了,这是为什么啊 难道网上说的都是错的? 问题补充:DataSource.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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><!-- 开启事务的注解必须加上 xmlns:tx="http://www.springframework.org/schema/tx" --> <!-- 开启注解处理器 --> <context:annotation-config /> <context:component-scan base-package="com.niit"> </context:component-scan> <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy> <!--<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /><property name="url" value="jdbc:oracle:thin:@192.168.1.2:1521:yldev" /><property name="username" value="ylnews" /><property name="password" value="ylnews" /> </bean>--> <!-- JDBC参数配置 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > <property name="locations"><list><value>classpath:/jdbc.properties</value></list></property></bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /> </bean> <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 如果要用hibernate注解 class改为org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean <property name="dataSource" ref="dataSource" /> <property name="mappingResources" > <list> <value>product.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value>hibernate.dialect=${hibernate.dialect}hibernate.show_sql=${hibernate.show_sql}hibernate.format_sql=${hibernate.format_sql}hibernate.cache.use_second_level_cache=falsehibernate.cache.provider_class=org.hibernate.cache.OSCacheProviderhibernate.cache.use_query_cache=falsehibernate.jdbc.fetch_size=50hibernate.jdbc.batch_size=30</value></property> </bean> --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><!-- 如果要用hibernate注解 class改为org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean --> <property name="dataSource" ref="dataSource" /> <!--<property name="annotatedClasses"> 指定注解方式的实体类<list><value>com.niit.entity.Accessory</value></list></property> --><property name="packagesToScan"> <!-- 扫描注解方式的实体类 --><list><value>com.niit.entity</value></list></property> <!-- <property name="mappingResources" > <list> <value>product.hbm.xml</value> </list> </property> --> <property name="hibernateProperties"> <!--<props> 另一种写法 <prop key="hibernate.dialect"> org.hibernate.dialect.OracleDialect </prop> <prop key="hibernate.show_sql"> true </prop> </props> --><value><!-- 设置数据库方言 -->hibernate.dialect=${hibernate.dialect}<!-- 输出SQL语句到控制台 -->hibernate.show_sql=${hibernate.show_sql}<!-- 格式化输出到控制台的SQL语句 -->hibernate.format_sql=${hibernate.format_sql}<!-- 是否开启二级缓存 -->hibernate.cache.use_second_level_cache=false<!-- 配置二级缓存产品 -->hibernate.cache.provider_class=org.hibernate.cache.OSCacheProvider<!-- 是否开启查询缓存 -->hibernate.cache.use_query_cache=false<!-- 数据库批量查询数 -->hibernate.jdbc.fetch_size=50<!-- 数据库批量更新数 -->hibernate.jdbc.batch_size=30<!--hibernate.current_session_context_class=thread--><!-- 配置事务后就不需要这行,否则需要这行 --></value></property> </bean> <!-- 配置事务管理器 就是指定义一个切面类--> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /><!-- 注入sessionFactory 通过数据库的连接来管理事务并且还需要知道hibernate的一些配置 --></bean><!-- 使用注解方式定义事务 有了这行@Transactional才能起作用--> <tx:annotation-driven transaction-manager="txManager"/> <!-- 配置事务传播特性 --><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="save*" propagation="REQUIRED" /><!-- 默认就是REQUIRED --><tx:method name="delete*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="get*" read-only="true" /><tx:method name="load*" read-only="true" /><tx:method name="find*" read-only="true" /><tx:method name="*" read-only="true" /><!-- 指上面之外的方法用这个 --></tx:attributes></tx:advice> <!-- 配置哪些类的哪些方法参与事务 --><aop:config> <aop:pointcut id="business" expression="execution(* com.niit.datasource..*.*(..))"/><!-- 匹配com.niit.datasource包及其子包所有类的所有方法 --><aop:advisor pointcut-ref="business" advice-ref="txAdvice" /></aop:config><bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"><property name="sessionFactory" ref="sessionFactory"></property></bean><bean id="hibernateDaoSupportDAO" class="com.niit.datasource.HibernateDaoSupportDAO"><property name="sessionFactory" ref="sessionFactory"></property></bean></beans>com.niit.entity.Accessory:package com.niit.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entitypublic class Accessory { private String aid; private String uploadfilename; private String uploadcontenttype; private String uploadrealname; private String news; @Id @GeneratedValuepublic String getAid() {return aid;}public void setAid(String aid) {this.aid = aid;}public String getUploadfilename() {return uploadfilename;}public void setUploadfilename(String uploadfilename) {this.uploadfilename = uploadfilename;}public String getUploadcontenttype() {return uploadcontenttype;}public void setUploadcontenttype(String uploadcontenttype) {this.uploadcontenttype = uploadcontenttype;}public String getUploadrealname() {return uploadrealname;}public void setUploadrealname(String uploadrealname) {this.uploadrealname = uploadrealname;}public String getNews() {return news;}public void setNews(String news) {this.news = news;} }com.niit.datasource.HibernateDaoSupportDAO2:package com.niit.datasource;import javax.annotation.Resource;import org.hibernate.SessionFactory;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.stereotype.Component;import com.niit.entity.Accessory;@Componentpublic class HibernateDaoSupportDAO2 extends HibernateDaoSupport { @Resource(name="sessionFactory")public void setSuperSessionFactory(SessionFactory sessionFactory){ super.setSessionFactory(sessionFactory); } public void save2(){Accessory accessory = new Accessory();accessory.setNews("2");accessory.setUploadcontenttype("2");accessory.setUploadfilename("3");accessory.setUploadrealname("2");this.getHibernateTemplate().save(accessory);}}com.niit.SpringDemo:package com.niit;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.junit.Test;import org.springframework.aop.support.AopUtils;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.niit.datasource.Dao;import com.niit.datasource.HibernateDaoSupportDAO;import com.niit.datasource.HibernateDaoSupportDAO2;import com.niit.datasource.HibernateDaoSupportInterface;import com.niit.service.HelloDao;import com.niit.service.HelloService;import com.niit.service.MyService;public class SpringDemo {/** * @param args */@Testpublic static void main(String[] args) {ClassPathXmlApplicationContext cpxac = new ClassPathXmlApplicationContext("DataSource.xml");HibernateDaoSupportDAO2 hibernateDaoSupportDAO2 = (HibernateDaoSupportDAO2)cpxac.getBean("hibernateDaoSupportDAO2");//这里用的是cglib代理不需要接口hibernateDaoSupportDAO2.save2();System.out.println(AopUtils.isCglibProxy(hibernateDaoSupportDAO2));System.out.println(AopUtils.isJdkDynamicProxy(hibernateDaoSupportDAO2)); }}
解决方案
你把其中一个bean实现的接口删掉(删掉后把原来用接口的地方都直接替换为实现类),再跑起来看看
解决方案二:
proxy-target-class 默认就是false 即如果你的类实现了接口 那么就是jdk动态代理 否则还是走cglib(因为无法走jdk动态代理 ) 这就是默认的情况(即proxy-target-class 不设置 即为false)proxy-target-class=true 即强制走cglib代理 即代理类 而不是接口