I started to work in a simple Spring web-service and getting the following errors provided below,
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'blogEntryController':
Injection of autowired dependencies failed; nested exception
is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private core.services.BlogEntryService
rest.mvc.BlogEntryController.service; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [core.services.BlogEntryService] 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)}
The project structure is as following,
Spring MVC project structure
I have the following service code,
package core.services;
import core.entities.BlogEntry;
public interface BlogEntryService {
public BlogEntry find(Long id); // Returns the BlogEntry or null if it can't be found
public BlogEntry delete(Long id); // Deletes the found BlogEntry or returns null if it can't be found
public BlogEntry update(Long id, BlogEntry data);
}
and, the following Controller code,
#Controller
#RequestMapping("/rest/blog-entries")
public class BlogEntryController {
#RequestMapping("/")
public String test(){
return "view";
}
public BlogEntryController() {
}
#Autowired
private BlogEntryService service;
public BlogEntryController(BlogEntryService service)
{
this.service = service;
}
#RequestMapping(value="/{blogEntryId}",
method = RequestMethod.GET)
public ResponseEntity<BlogEntryResource> getBlogEntry(
#PathVariable Long blogEntryId) {
BlogEntry entry = service.find(blogEntryId);
if(entry != null)
{
BlogEntryResource res = new BlogEntryResourceAsm().toResource(entry);
return new ResponseEntity<BlogEntryResource>(res, HttpStatus.OK);
} else {
return new ResponseEntity<BlogEntryResource>(HttpStatus.NOT_FOUND);
}
}
}
Update: Dispatcher Servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="rest.mvc"/>
<mvc:annotation-driven/>
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
I created the empty constructure as it was asked by the debugger earlier. I cant even see the view.jsp file returned from the test method. What should I do now ?
As I stated in my first comment beneath your question, you are missing the implementation class of the interface. An implementation class could be the one below, however you have to provide the functionality of the methods:
#Service
public class BlogEntryServiceImpl implements BlogEntryService {
public BlogEntry find(Long id) {
//Do your stuff here
}
public BlogEntry delete(Long id) {
//Do your stuff here
}
public BlogEntry update(Long id, BlogEntry data) {
//Do your stuff here
}
}
#Autowired
private BlogEntryService service;
Above lines says you are having class BlogEntryService annotated
with #Service or mentioned in bean tag or as component scan(package) in dispatcher-servlet xml.
If you are missing mentioning in any of one place you will get the exception No qualifying bean of type [core.services.BlogEntryService] found for dependency:
So your BlogEntryService interface should be
#Service
public interface BlogEntryService {
Update : In dispathcer-servlet.xml you have to mention the packages to scan for beans.In your case it is rest.mvc.Since it's an Interface you should have the implemented class(annotated with #Service),which will have definition of interface methods.
<context:component-scan base-package="Your Service layer Package" />
It looks that BlogEntryService bean class is not provided. Do you have some implementation class annotated wit #Service?
Either you provide an implementation class for your interface and annotate it with #service, OR make the BlogEntryService interface extend CrudRepository and Spring will provide you with the proper implementation for your cruds :save, getAll, find...
It looks like an implementation of your service is missing.
Just annotating an interface with #Service is not enough for Spring to generate a bean unless you are extending your interface with some of the specific Spring Data interface (CrudRepository, Repository ...). In that specific case and if you respect sone convention Spring will be able to automatically generate the implementation for you.
Please have a look to the documentation: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories
Related
I'm trying to autowire an interface inside a controller bean
In my context configuration file I've put
<context:annotation-config />
and
<bean id="viewVerbale" class="com.sirfe.controller.VerbaliController" />
my controller class is
#Controller
public class VerbaliController {
#Autowired
VerbaliRepository repository;
private static final Logger logger = LoggerFactory.getLogger(VerbaliController.class);
#RequestMapping(value = "/sirfe/verbale/{sequVerbale:.+}", method = RequestMethod.GET)
public ModelAndView viewVerbale(#PathVariable("sequVerbale") String sequVerbale) {
logger.debug("welcome() - sequVerbale {}", sequVerbale);
Verbali verbale = repository.findOne(Long.parseLong(sequVerbale));
ModelAndView model = new ModelAndView();
model.setViewName("sirfe/verbali/viewVerbale");
model.addObject("sequVerbale", sequVerbale);
return model;
}
}
my interface signature is
public interface VerbaliRepository extends CrudRepository<Verbali, Long> { }
and when I launch my app I get
Could not autowire field: com.sirfe.repository.VerbaliRepository com.sirfe.controller.VerbaliController.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sirfe.repository.VerbaliRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Looks like you're trying to use Spring JPA repository.
In order to have Spring create bean for your repository interfaces, you need in applicationContext.xml to declare what package to scan
<jpa:repositories base-package="com.sirfe.repository" />
Doing so, Spring will generate bean implementing the interface for you.
See Spring JPA Repositories
Spring is complaining that it cannot find a valid bean definition that matches, ie there is no bean defined that is an implementation of VerbaliRepository.
You need to define a bean or alternatively annotate an implementation class with #Component eg
<bean id="myRepository" class="com.foo.bar.MyRepository" />
or
#Component
public class MyRepository implements VerbaliRepository {
....
}
I have my mailing service with has constructor argument and implements an interface
public class MailServiceImpl implements MailService {
private MailBo mail;
public MailBO getMail() {
return Mail;
}
public void setMail(MailBO Mail) {
this.Mail = Mail;
}
public MailServiceImpl(MailBo mail) {
throw exception if from and to address is not here
this.mail = mail;
}
public void sendMail(){
use mail object to send mail here
}
}
so now i am trying to write a test which i want to create Mailserviceimpl instance autowired with constructor argument passed in it.
i followed this link to autowire object with constructor, but i am getting below exception
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.model.MailBO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
my test class
public class MailServiceImplTest {
#Autowired
private MailService mailServiceImpl;
#Test
public void testSendValidMail(){
//test
}
}
EDIT:-
adding spring context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.service" />
</beans>
EDIT 2:-
i want my mailbo loaded with some values and inject as constructor object to mailserviceimpl
I assume that MailServiceImpl and MailBO are Spring Beans. Then just annotate MailServiceImpl constructor by #Autowired and Spring will automatically injects constructor dependency
I developed a basic app containing 2 projects. First one is data layer and the second is a web app (mvc project)
data layer contains the following
#Entity
#Table(name="users")
public class User implements Serializable {
.....
}
public interface UserBase {
.....
}
#Repository
public interface UserRepository extends JpaRepository <User, Long>{
}
#Service
public class UserImpl implements UserBase {
private final UserRepository repository;
#Autowired
public UserImpl(UserRepository repository) {
this.repository = repository;
......
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("Config/applicationContext.xml")
public class testcase1 {
#Autowired
private UserImpl userImpl;
#Test
public void test() {
.....
UserImpl.save(user);
.....
}
web app
#Controller
public class ManageUser {
#Autowired
UserImpl userImpl;
#RequestMapping("/addUser/")
public ModelAndView addUser() {
UserImpl.save(user);
.....
}
}
When I run the unit test the code succeeded and no error found.
But when I put the output jar from data layer into the spring mvc web app the lib folder and added reference to the data layer in the build bath , I have an error message
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.my.domin.impl.UserImpl
Note:
I use tomcat.
I use the flowing config:
<jpa:repositories base-package="com.sanatech.repository" />
<context:component-scan base-package="com.my.repository"/>
<context:component-scan base-package="com.my.domin.impl"/>
<context:component-scan base-package="com.my.domin"/>
<context:component-scan base-package="com.my"/>
<context:component-scan base-package="com.my.manageuser.controller"/>
<tx:annotation-driven/>
<context:annotation-config />
Edit
when I separated the unit test to a new project and added reference to the data layer jar in the build bath I found the same exception.
Are you sure this exception is't raised from your testcase:
public class testcase1 {
#Autowired
private UserImpl userImpl;
You can explicitly set bean name in #Service annotation and use this name in #Autowired to make sure of correct configuration.
I'm writing my own scope (i.e. a class which implements org.springframework.beans.factory.config.Scope) and I need some beans injected. How do I do that?
Background: Spring must create all scope beans first so that I can define which beans go into the scope. But what about beans that I need to build the scope in the first place?
I came up with this workaround which seems to be pretty safe but I'd like to hear comments (or maybe my answer gives you some better ideas):
Define the scope and give it setters (instead of using #Autowired)
Create a "scope configurer" bean:
public CustomScopeConfigurer {
#Autowired private Foo foo;
private CustomScope scope;
public CustomScopeConfigurer( CustomScope scope ) {
this.scope = scope;
}
#PostConstruct
public void initScope() {
scope.setFoo( foo );
}
}
This configurer bean must not be lazy.
Reasoning:
The scope itself can't use autowiring because it is created before the first bean. While it might be created later, you can be sure that it will be created before every other bean. So autowiring can't work reliably.
The configurer bean will be created alongside all the other beans but after the scope. So autowiring will work for it.
Since the configurer bean isn't initialized lazy, it will be created before the rest of the application can see the application context. This means that no beans for the scope (i.e. beans with #Scope("custom")) can have been created at this time - the scope can't be "active", yet -> Spring won't have tried to put any beans into it, yet.
The scope itself is usually created as a static constant somewhere. That's why we have to pass it as an argument to the constructor.
You can do that very simply.
Consider the below Custom scope class:
package com.way2learn;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
public class MyCustomScope implements Scope{
private Map<String, Object> scope;
public void setScope(Map<String, Object> scope) {
this.scope = scope;
}
#Override
public Object get(String name, ObjectFactory<?> objectFactory) {
checkAndClear();
Object bean=scope.get(name);
if(bean==null){
bean=objectFactory.getObject();
scope.put(name,bean);
}
return bean;
}
private void checkAndClear() {
//Some logic to check condition and clear the scope
}
//optional methods
#Override
public Object remove(String name) {
// TODO Auto-generated method stub
return null;
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
}
#Override
public Object resolveContextualObject(String key) {
// TODO Auto-generated method stub
return null;
}
#Override
public String getConversationId() {
// TODO Auto-generated method stub
return null;
}
}
It has dependency on java.util.Map.
You can not autowire using #Autowired it as #Autowired annotation works after AutoWiredAnnotationBeanPostProcessor only.
But Custom scopes will be registered before AutoWiredAnnotationBeanPostProcessor.
So you can manually inject Map into MyCustomScope class as below:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<util:map key-type="java.lang.String" value-type="java.lang.Object" id="custScopeMap"/>
<bean id="myCustomScope" class="com.way2learn.MyCustomScope">
<property name="scope" ref="custScopeMap"/>
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myScope" value-ref="myCustomScope"/>
</map>
</property>
</bean>
</beans>
I tried it. It works fine. And I found a bug in Aaron Digulla's answer i.e.
Consider the below scenario: First Spring's CustomScopeConfigurer bean will be created, immediately CustomScope bean will be created and now our custom scope is ready to use. After some time Aaron Digulla's CustomScopeConfigurer will be created which initializes foo into CustomScope. But what happenes if some custom scoped beans are created after CustomScope registration and before Aaron Digulla's CustomScopeConfigurer bean creation? For those beans there will be not foo in the CustomScope bean.
I am trying to get Aspect working with Spring 3 and annotations.
#Aspect
public class AttributeAspect {
#Pointcut("#annotation(com.mak.selective.annotation.Attribute)")
public void process(){
System.out.println("Inside Process ....");
}
#Around("process()")
public void processAttribute(){
System.out.println("Inside Actual Aspect ..");
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="false" />
<context:component-scan base-package="com.mak.selective.annotation.*" />
<bean name="attribute" class="com.mak.selective.annotation.AttributeAspect"/>
</beans>
MY Test to test the Aspect:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/springcontext/*.xml")
public class AttributeTest {
#Attribute(tableName = "firstTable", columnName = "New Column")
private void getAttribute() {
System.out.println("Inside Attribute call...");
}
#Test
public void testAttributeAspect() {
getAttribute();
}
}
With this code i can only see "Inside Attribute call..." but nothing from Aspect.
Please guide.
Got this working by making a new Object (Component) and injected to the Junit test class.
Good to see that you got it working from XML, but you could have also done it from annotations.
The issue is that the #Aspect annotation is not a Spring stereotype, so the scanner is not registering the aspect as a Spring Bean. Just add either #Service or #Component above or below #Aspect and it will be registered.
Also, either directly name the bean (e.g., #Service("myNamedService")) or have it implement an interface (e.g., public class AttributeAspect implements IAspect {), as per standard Spring design.
You need to use real AspectJ if you want to intercept invocations of methods within the same bean form where it is invoked. (What you have done, should work if the method testAttributeAspect() is located in an other bean.)
How to do real AspectJ?
Using the AspectJ compiler and weaver enables use of the full AspectJ language, and is discussed in Section 7.8, “Using AspectJ with Spring applications”.
#See Spring Reference
A few things:
Firstly, when you do around advice you need to write the advice method like this:
#Around(...)
public void aroundAdviceMethod(ProceedingJoinPoint pjp) throws Throwable {
try {
System.out.println("before...");
pjp.proceed();
}
finally {
System.out.println("After...");
}
}
But also (and this at least applies when you're using proxies, not entirely sure in your case), the method you're putting advice on needs to be public (yours isn't), spring managed (via #Component or otherwise) and called external from the class so the proxy can take effect (also not the case in your example). So you need something like this:
#Component
public class SomeClass {
#Attribute
public void someMethodCall() {
System.out.println("In method call");
}
}
public class SomeUnitTest {
#Autowired SomeClass someClass;
#Test
public void testAspect() {
someClass.someMethodCall();
}
}