Прокси CGLIB не создается для транзакционных прокси

Вот что я делаю:

@Component("jdbcBookDao")
public class JdbcBookDao extends JdbcDaoSupport implements BookDao{

@Autowired
public void injectDataSource(DataSource dataSource){
    setDataSource(dataSource);
}

@Transactional
public int getStock(int isbn){
    String sql = "SELECT bs.STOCK FROM BOOK b, BOOK_STOCK bs WHERE b.id=bs.book_id AND b.isbn=?";
    return getJdbcTemplate().queryForInt(sql, isbn);
}
}

И в контексте приложения я объявил:

<tx:annotation-driven proxy-target-class="true"/> 

С этой конфигурацией я ожидал, что когда я извлекаю jdbcBookdao из контекста, это будет прокси-сервер CGLIB (поскольку я установил для proxy-target-class значение true). Но когда я отлаживаю, он появляется как экземпляр JdkDynamicAopProxy. Может кто-нибудь объяснить, почему прокси-сервер JDK создается, даже когда я запросил прокси-сервер CGLIB?

Спасибо.


person Prasanth    schedule 05.04.2013    source источник
comment
У вас нет предупреждения о том, что классы библиотеки CGLIB не найдены?   -  person DessDess    schedule 05.04.2013
comment
У меня есть CGLIB в моих зависимостях maven. Также я не вижу никаких предупреждений в моем журнале.   -  person Prasanth    schedule 05.04.2013
comment
Не вижу причин, по которым тогда это не сработало бы, возможно, вы что-то упустили: static.springsource.org/spring/docs/3.0.0.M3/reference/html/, но с моей точки зрения я не вижу никаких   -  person DessDess    schedule 05.04.2013
comment
Пытался отлаживать код Spring. И вот что я наблюдал. Стратегия создания прокси-сервера правильно выглядит как CglibSubclassingInstantiationStrategy. Это я проверил в методе instanceiateBean() класса AbstractAutowireCapableBeanFactory. Внутри этого instanceiateBean я вижу код Не переопределять класс с помощью CGLIB, если нет переопределений. Здесь проверка beanDefinition.getMethodOverrides().isEmpty() не удалась, и был создан динамический прокси-сервер JDK. Не уверен, почему это происходит.   -  person Prasanth    schedule 05.04.2013
comment
Также заметил, что если я включаю прокси-целевой класс через AOP Config, это работает отлично, т.е. создаются транзакционные прокси-серверы cglib. Но если у меня нет конфигурации AOP и я пытаюсь включить проксирование CGLIB с помощью ‹tx:annotation-driven›, это не работает.   -  person Prasanth    schedule 05.04.2013
comment
Интересный факт, потому что в документации сказано: Для ясности: использование 'proxy-target-class=true' в элементах ‹tx:annotation-driven/›, ‹aop:aspectj-autoproxy/› или ‹aop:config/› приведет к принудительному использованию прокси CGLIB для всех трех из них. но с тем, что вы сказали, это не так   -  person DessDess    schedule 05.04.2013


Ответы (1)


Spring исходный код в объект в соответствии с вами, если вы используете интерфейс, а затем прокси-сервер JDK, если вы используете обычный класс, то cgLib.

e   public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface()) {
            return new JdkDynamicAopProxy(config);
        }
        if (!cglibAvailable) {
            throw new AopConfigException(
                    "Cannot proxy target class because CGLIB2 is not available. " +
                    "Add CGLIB to the class path or specify proxy interfaces.");
        }
        return CglibProxyFactory.createCglibProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}nter code here
person zg_spring    schedule 26.06.2013
comment
Это поведение по умолчанию. Но мы можем переопределить это, указав для атрибута «proxy-target-class» значение «true». - person Prasanth; 28.06.2013