为什么使用@Transactional方法的类不能自动装配?

时间:2015-05-20 08:21:00

标签: java spring spring-security

我使用Spring Security和WAFFLE过滤器,根据ActiveDirectory服务器对用户进行身份验证。 我创建了一个额外的过滤器,用于根据我的数据库对用户进行身份验证(它只是检查是否 以前经过身份验证的用户在数据库中)。这是使用UserDetailsService

的实现完成的

此组合一直有效,直到我向服务添加了@Transactional带注释的方法。现在的服务 无法自动连接到过滤器。

这是服务类:

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private LdapUserDao ldapUserDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return getUserByUsername(username);
    }

    public User getUserByUsername(final String username) {
        final User databaseUser = userRepository.findByUsername(username);
        final User ldapUser = ldapUserDao.findByUsername(username);

        if (null == databaseUser || null == ldapUser) {
            return null;
        }

        final User user = mergeUsers(databaseUser, ldapUser);

        return user;
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @Transactional
    public void storeUser(final User user) {
        userRepository.save(user);
    }

    private User mergeUsers(final User database, final User ldap) {
        final User mergedUser = new User();

        mergedUser.setId(database.getId());
        mergedUser.setUsername(database.getUsername());
        mergedUser.setEnabled(database.isEnabled());
        mergedUser.setRoles(database.getRoles());

        mergedUser.setEmail(ldap.getEmail());
        mergedUser.setFirstName(ldap.getFirstName());
        mergedUser.setLastName(ldap.getLastName());
        mergedUser.setLocale(ldap.getLocale());

        return mergedUser;
    }

}

这是过滤器:

public class WaffleAuthenticationWrapperFilter extends GenericFilterBean {

    @Autowired
    private UserService userService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        final SecurityContext securityContext = SecurityContextHolder.getContext();
        final Authentication authentication = securityContext.getAuthentication();

        if (null == authentication || !(authentication instanceof WindowsAuthenticationToken)) {
            chain.doFilter(request, response);
            return;
        }

        final WindowsAuthenticationToken waffleAuthentication = (WindowsAuthenticationToken) authentication;
        final String username = waffleAuthentication.getName().replaceAll("^.*\\\\", "");
        final User user = userService.getUserByUsername(username);

        if (null == user) {
            securityContext.setAuthentication(null);
            return;
        }

        final WaffleAuthenticationWrapper authenticationWrapper = new WaffleAuthenticationWrapper(waffleAuthentication,
                user);

        securityContext.setAuthentication(authenticationWrapper);

        chain.doFilter(request, response);
    }

}

一旦删除@Transactional,项目就会再次编译。为什么不能将方法注释为@Transactional

这是stacktrace:

Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at my.project.App.main(App.java:13)
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:75)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
    ... 7 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.auth.WaffleAuthenticationWrapperFilter my.project.config.WebSecurityConfig.waffleAuthenticationWrapperFilter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:209)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:165)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:160)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:143)
    at org.springframework.boot.context.embedded.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:74)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:234)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:206)
    at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5151)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.auth.WaffleAuthenticationWrapperFilter my.project.config.WebSecurityConfig.waffleAuthenticationWrapperFilter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 35 more
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.auth.WaffleAuthenticationWrapperFilter my.project.config.WebSecurityConfig.waffleAuthenticationWrapperFilter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164)
    at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1365)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606)
    ... 37 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.auth.WaffleAuthenticationWrapperFilter my.project.config.WebSecurityConfig.waffleAuthenticationWrapperFilter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:512)
    at org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers(AutowiredWebSecurityConfigurersIgnoreParents.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161)
    ... 41 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.auth.WaffleAuthenticationWrapperFilter my.project.config.WebSecurityConfig.waffleAuthenticationWrapperFilter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 63 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waffleAuthenticationWrapperFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1127)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 65 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.project.services.UserService my.project.auth.WaffleAuthenticationWrapperFilter.userService; nested exception is java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 76 more
Caused by: java.lang.IllegalArgumentException: Can not set my.project.services.UserService field my.project.auth.WaffleAuthenticationWrapperFilter.userService to com.sun.proxy.$Proxy84
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
    at java.lang.reflect.Field.set(Unknown Source)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:557)
    ... 78 more

3 个答案:

答案 0 :(得分:10)

要应用AOP spring使用代理,它们有两种风格JDK Dynamic Proxies(基于接口)和基于CgLIB的代理(基于类)。默认情况下,Spring将JDK Dynamic Proxies用于实现1个或更多接口的类。

在运行时,您将获得一个动态创建的对象(代理),该对象实现它所包装的类的所有接口(UserDetailsService)(UserService)。因此动态创建的对象是UserDetailsService而不是UserService

因此,代理无法转换为UserService的错误。

你有(至少)两种方法来解决这个问题

  1. 编程到接口
  2. 启用基于类的代理。
  3. 编程到接口

    当您调用getUserByUsername时,您需要创建一个新界面并实现此功能以及UserDetailsService

    public interface UserService {
        User getUserByUsername(String username);
        void storeUser(User user);
        List<User> findAllUsers();
    }
    
    @Service("userService")
    public class UserServiceImpl implements UserDetailsService, UserService { ... }
    

    如果你这样做,你可以保持你的过滤器不受影响,因为UserService现在只是一个界面。如果为接口指定其他名称,则还必须将过滤器中的UserService字段更改为该类型。

    启用基于类的代理

    当您使用Spring启动时,启用基于类的代理就像在application.properties文件中添加属性一样简单。

    spring.aop.proxy-target-class=true
    

    这将创建一个基于类的代理,这样您就可以保持过滤器的代码不变。

答案 1 :(得分:2)

@Autowired
private UserService userService;

应该成为

@Autowired
private UserDetailsService  userService;

因为您的@Transactional代理不是UserService的实例,而是UserDetailService(您的界面)的实例

答案 2 :(得分:1)

正如@mdeinum指出的那样,java中的本机代理只能代理接口,而不能代理类。这也是最佳做法。所以你必须这样做:

@Autowired
private IUserService userService;

然后

public class UserService implements IUserService

然而,有些情况(特别是AOP)无法实现。如果是这种情况,您可以使用cglib代理而不是本机Java代理。你必须将它添加到你的(maven?)依赖项:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>${cglib.version}</version>
    </dependency>

告诉spring-aop代理类:

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