Guava打破了Spring boot的启动

时间:2016-05-20 12:29:42

标签: spring-boot guava

当关注LeanStacks的说明视频时,使用Guava添加缓存没有问题。对我自己的项目做同样的事情会在启动时给我一个org.springframework.beans.factory.BeanCreationException。

我试图一次拿走一件,直到我把它工作,然后把它归结为当我向我的UserServiceBean类添加一个@Cacheable注释时它会中断。

我的一个怀疑是因为我的实体类之间的关系而发生这种情况。可能是这种情况吗?否则会导致什么?

来自pom.xml

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

我的应用程序配置如下:

@SpringBootApplication
@EnableCaching
public class Application {

    public static void main( String [] args ) {
        SpringApplication.run( Application.class, args );
    }

    @Bean
    public CacheManager cacheManager(){
        GuavaCacheManager cacheManager = new GuavaCacheManager( "EntWeb" );

        return( cacheManager );
    }
}

UserServiceBean.java

@Service
public class UserServiceBean implements UserService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserRepository userRepo;

    @Override
    public User create(User user) {
        User ret = null;

        if( user.getId() == null ) {
            ret = userRepo.save( user );
        }

        return( ret );
    }

    @Override
    //This is what breaks the startup procedure!
    @Cacheable( value="EntWeb", key="#id")
    public User findOne(Long id) {
        User ret = userRepo.findOne( id );

        return( ret );
    }

... other service functions

User.java

@Entity(name="USERS")
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String firstName;

    private String lastName;

    private String email;

    @OneToOne(cascade=CascadeType.PERSIST)
    @JoinColumn( name="addressId" )
    private Address address;

... getters and setters

错误信息:

Exception encountered during context initialization - cancelling
refresh attempt:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'userController': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private org.entweb.persistence.UserServiceBean
org.entweb.web.api.UserController.userService; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type [org.entweb.persistence.UserServiceBean]
found for dependency: expected at least 1 bean which qualifies as
autowire candidate for this dependency. Dependency annotations
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

帮助表示赞赏

编辑1:UserController.java

package org.entweb.web.api;

import java.util.Collection;

import org.entweb.model.User;
import org.entweb.persistence.UserServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping( value = "/api/users" )
public class UserController {

    @Autowired
    private UserServiceBean userService;

    @RequestMapping( 
            method = RequestMethod.POST, 
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<User> CreateUser( @RequestBody User user) {
        User persistedUser = userService.create(user);
        ResponseEntity<User> ret = null;

        if( null != persistedUser ) {
            ret = new ResponseEntity< User >(persistedUser, HttpStatus.OK );
        }
        else {
            ret = new ResponseEntity< User >( HttpStatus.INTERNAL_SERVER_ERROR );
        }

        return( ret );
    }

    @RequestMapping( value="/{userId}", method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
    public ResponseEntity< User > GetUser( @PathVariable( "userId" ) Long id) {
        User user = userService.findOne(id);
        ResponseEntity< User > ret = null;

        if( null != user ) {
            ret = new ResponseEntity< User >(user, HttpStatus.OK);
        }
        else {
            ret = new ResponseEntity< User >( HttpStatus.NOT_FOUND );
        }

        return( ret );
    }

    @RequestMapping( method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
    public ResponseEntity< Collection< User > > GetAllUsers() {
        Collection< User > users = userService.findAll();

        return( new ResponseEntity< Collection< User > >( users, HttpStatus.OK ) );
    }

    @RequestMapping( 
            value = "/{userId}",
            method = RequestMethod.PUT, 
            produces = MediaType.APPLICATION_JSON_VALUE, 
            consumes = MediaType.APPLICATION_JSON_VALUE )
    public ResponseEntity< User > UpdateUser( @RequestBody User user ) {
        ResponseEntity< User > ret = null;
        User updatedUser = userService.update(user);

        if( null == updatedUser ){
            ret = new ResponseEntity< User >( HttpStatus.NOT_FOUND );
        }
        else{
            ret = new ResponseEntity< User >( updatedUser, HttpStatus.OK );
        }

        return( ret );
    }

    @RequestMapping( value="/{userId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity< User > DeleteUser( @PathVariable( "userId" ) Long id ){
        userService.delete(id);

        return( new ResponseEntity< User >( HttpStatus.NO_CONTENT ));
    }

    @RequestMapping(
            value = "/search",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE
            )
    public ResponseEntity< Collection< User > > UserSearch( @RequestParam( "type" ) String queryType, @RequestParam( "value" ) String value ){
        Collection< User > resp = null;
        ResponseEntity< Collection< User > > ret = null;

        switch( queryType ) {
        case "email": resp = userService.findByEmail( value ); break;
        default:
            resp = null;
        }

        if( resp.size() < 1 ){
            ret = new ResponseEntity<>( HttpStatus.NOT_FOUND );
        }
        else{
            ret = new ResponseEntity<>( resp, HttpStatus.OK );
        }

        return( ret );
    }
}

1 个答案:

答案 0 :(得分:2)

更改

@Autowired
private UserServiceBean userService;

@Autowired
private UserService userService;

原因是,Spring为您的类创建了一个代理来实现缓存功能。但是,它默认使用JDK代理,当bean实现接口时,JDK代理也实现接口,但不扩展bean类。因此bean只有UserService类型而不是UserServiceBean类型。此外,对字段使用bean实现类型也没有用,因为这是接口的用途。您希望对接口进行编码,而不是实现。