I create simple news system with comments using Spring Boot and MongoDB. I would like to focus on code quality. I create service using generic to save data from class.
My code:
Dao.java
@Repository
public interface Dao<T, ID extends Serializable> extends MongoRepository<T, ID>{
}
DaoService.java
@Service
public class DaoService<T> extends AbstractService<T, Long> {
@Autowired
public DaoService(Dao<T, Long> dao) {
super(dao);
}
}
Service.java
@org.springframework.stereotype.Service
public interface Service<T, ID extends Serializable> {
T save(T entity);
}
AbstractService.java
public abstract class AbstractService<T, ID extends Serializable> implements
Service<T, ID> {
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected Dao<T, ID> dao;
public AbstractService(Dao<T, ID> dao) {
this.dao = dao;
}
@Override
public T save(T entity) {
this.logger.debug("Create a new {} with information: {}", entity.getClass(),
entity.toString());
return this.dao.save(entity);
}
}
and 2 repo
@Repository
public interface CommentDao extends Dao<Comment, Long> {
}
and
@Repository
public interface NewsDao extends Dao<News, Long> {
}
My controller:
@RestController
@RequestMapping("/news")
public class NewsController {
private final DaoService<News> newsService;
private final DaoService<Comment> commentDaoService;
public NewsController(DaoService<News> newsService, DaoService<Comment> commentDaoService) {
this.newsService = newsService;
this.commentDaoService = commentDaoService;
}
@RequestMapping(method = RequestMethod.GET)
public void save(){
newsService.save(new News("elo","a","c"));
commentDaoService.save(new Comment("iss","we"));
}
}
error:
2016-03-02 23:22:30.265 WARN 6100 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'daoService' defined in file [C:\Users\Lukasz\IdeaProjects\NewsSystem_REST\build\classes\main\com\newssystem\lab\dao\DaoService.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.newssystem.lab.dao.Dao]: : No qualifying bean of type [com.newssystem.lab.dao.Dao] is defined: expected single matching bean but found 2: newsDao,commentDao; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.newssystem.lab.dao.Dao] is defined: expected single matching bean but found 2: newsDao,commentDao
2016-03-02 23:22:30.273 INFO 6100 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat
2016-03-02 23:22:30.296 ERROR 6100 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'daoService' defined in file [C:\Users\Lukasz\IdeaProjects\NewsSystem_REST\build\classes\main\com\newssystem\lab\dao\DaoService.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.newssystem.lab.dao.Dao]: : No qualifying bean of type [com.newssystem.lab.dao.Dao] is defined: expected single matching bean but found 2: newsDao,commentDao; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.newssystem.lab.dao.Dao] is defined: expected single matching bean but found 2: newsDao,commentDao
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at com.newssystem.lab.NewsSystemApplication.main(NewsSystemApplication.java:18) [main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) [idea_rt.jar:na]
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.newssystem.lab.dao.Dao] is defined: expected single matching bean but found 2: newsDao,commentDao
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
... 24 common frames omitted
You must use the qualifier annotation to define which bean will be injected into your service. On Spring an interface can have many implementations, but if none of those implementations has the primary annotation defined Spring does not know which one to pick automatically.
@Autowired
@Qualifier("bean-name")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.