当关注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 );
}
}
答案 0 :(得分:2)
更改
@Autowired
private UserServiceBean userService;
到
@Autowired
private UserService userService;
原因是,Spring为您的类创建了一个代理来实现缓存功能。但是,它默认使用JDK代理,当bean实现接口时,JDK代理也实现接口,但不扩展bean类。因此bean只有UserService
类型而不是UserServiceBean
类型。此外,对字段使用bean实现类型也没有用,因为这是接口的用途。您希望对接口进行编码,而不是实现。