#Autowired not working in spring Integration - spring

In service implementation,with help of #Autowired i am injecting CollectInfo object in serviceImpl but i am getting NullPointerException.
package net.group.cts.service.serviceImpl;
#Service
public class EmployeeImpl implements EmployeeService {
#Autowired
CollectInfo info;
public void processData(){
info.getName();
}
}
package net.group.cts.model;
#Component
public class CollectInfo (){
String name;
public String getName(){
name = name + "Mr.";
return name;}
}
}
Xmlconfig.xml
<context:annotation-config/>
<context:component-scan base-package="net.group.cts"/>
<bean id="info" class="net.group.emp.model.CollectInfo "/>

You cannot inject a bean in a class if this class is not a Spring bean.
EmployeeImpl is not annotated with any Spring bean stereotype such as #Component or #Service.
Add one of them on EmployeeImpl and ensure that the two classes are located inside the package scanned by Spring <context:component-scan base-package="net.group.emp.service"/>
and it should be ok.
Besides, both annotating a bean with #Component :
#Component
public class CollectInfo (){...}
and configuring it in the Spring xml configuration :
<bean id="info" class="net.group.emp.model.CollectInfo "/>
is redundant. It will finally create two beans : one name collectInfo and another named info.
I advise you to favor annotation over xml configuration as it is possible (it is the very most of cases).

Related

#Autowired dependencies are null in compile time weaving of #Aspect class [duplicate]

I have the following spring configuration:
<context:component-scan base-package="uk.co.mysite.googlecontactsync.aop"/>
<bean name="simpleEmailSender" class="uk.co.mysite.util.email.simple.SimpleEmailSenderImplementation"/>
<aop:aspectj-autoproxy/>
Then I have an aspect:
#Aspect
public class SyncLoggingAspect {
#Autowired
private SimpleEmailSender simpleEmailSender
#AfterReturning(value="execution(* uk.co.mysite.datasync.polling.Poller+.doPoll())", returning="pusher")
public void afterPoll(Pusher pusher) {
simpleEmailSender.send(new PusherEmail(pusher));
}
}
This aspect works (I can hit a breakpoint on afterPoll) but simpleEmailSender is null. Unfortunately I cannot find clear documentation on why this is. (For the record, my simpleEmailSender bean exists and is correctly wired into other classes) The following things confuse me:
Is context:component-scan supposed to be picking up #Aspect? If it is then surely it would be a spring managed bean, thus autowired should work?
If context:component-scan isn't for creating aspects, how is my aspect being created? I thought aop:aspectj-autoproxy just creates a beanPostProcessor to proxy my #Aspect class? How would it do this if it isn't a spring managed bean?
Obviously you can tell I don't have an understanding of how things should be working from the ground up.
The aspect is a singleton object and is created outside the Spring container. A solution with XML configuration is to use Spring's factory method to retrieve the aspect.
<bean id="syncLoggingAspect" class="uk.co.demo.SyncLoggingAspect"
factory-method="aspectOf" />
With this configuration the aspect will be treated as any other Spring bean and the autowiring will work as normal.
You have to use the factory-method also on Enum objects and other objects without a constructor or objects that are created outside the Spring container.
For Spring Boot to use #Autowired with AspectJ I have found the following method.
In configuration class add your aspect:
#Configuration
#ComponentScan("com.kirillch.eqrul")
public class AspectConfig {
#Bean
public EmailAspect theAspect() {
EmailAspect aspect = Aspects.aspectOf(EmailAspect.class);
return aspect;
}
}
Then you can successfully autowire your services in your aspect class:
#Aspect
public class EmailAspect {
#Autowired
EmailService emailService;
Another option is to add #Configurable to your aspect class instead of messing around with XML.
Configuring #Autowired with java config only (so no XML based configuration) requires a bit of extra work than just adding #Configuration to the class, as it also needs the aspectOf method.
What worked for me was creating a new class:
#Component
public class SpringApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
And then use that in you aspect in conjunction with using #DependsOn #Configured and #Autowired:
#DependsOn("springApplicationContextHolder")
#Configuration
#Aspect
public class SomeAspect {
#Autowired
private SomeBean someBean;
public static SomeAspect aspectOf() {
return SpringApplicationContextHolder.getApplicationContext().getBean(SomeAspect.class);
}
The #DependsOn is needed because spring can't determine the dependency because the bean is used staticly.
I dont have 50 rep to comment on a question so here is another answer relating to #
Jitendra Vispute answer.
The official Spring doc mentions:
You may register aspect classes as regular beans in your Spring XML configuration, or autodetect them through classpath scanning - just like any other Spring-managed bean. However, note that the #Aspect annotation is not sufficient for autodetection in the classpath: For that purpose, you need to add a separate #Component annotation (or alternatively a custom stereotype annotation that qualifies, as per the rules of Spring’s component scanner).Source: Spring '4.1.7.Release' documentation.
This would mean that adding a #Component annotation and adding the #ComponentScan on your Configuration would make #Jitendra Vispute's example work. For the spring boot aop sample it worked, though I did not mess around with context refreshing.Spring boot aop sample:
Application:
package sample.aop;
#SpringBootApplication
public class SampleAopApplication implements CommandLineRunner {
// Simple example shows how an application can spy on itself with AOP
#Autowired
private HelloWorldService helloWorldService;
#Override
public void run(String... args) {
System.out.println(this.helloWorldService.getHelloMessage());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleAopApplication.class, args);
}
}
The application should also run as plain Spring Framework application with the following annotations instead of #SpringBootApplication:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan
and an AnnotationConfigApplicationContext instead of SpringApplication.
Service:
package sample.aop.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class HelloWorldService {
#Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}
Monitor Aspect:
package sample.aop.monitor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class ServiceMonitor {
#AfterReturning("execution(* sample..*Service.*(..))")
public void logServiceAccess(JoinPoint joinPoint) {
System.out.println("Completed: " + joinPoint);
}
}
This blog post explains it really well. Due to the fact that aspect singleton is created outside spring container you'd need to use factory-method=”aspectOf” that is only available after it is woven in by AspectJ ( not Spring AOP ) :
Notice factory-method=”aspectOf” that tells Spring to use a real
AspectJ ( not Spring AOP ) aspect to create this bean. So that after
the aspect is woven in it has an
“aspectOf” method.
So that :
No matching factory method found: factory method 'aspectOf()' - That
would mean that the aspect was not woven by AspectJ weaver.
From my experience with spring 3.1, if I don't use #Autowired but traditional setter for dependency injection, it gets injected and works as expected without aspectJ weaver. Although I'm encountering problems with the aspect being singleton... It results in 'perthis' instantiation model.
.
Add #Component to aspect class and your dependencies should get injected automatically.
and add context:component-scan for package where your aspect is in spring context file.
#Component
#Aspect
public class SomeAspect {
/* following dependency should get injected */
#Autowired
SomeTask someTask;
/* rest of code */
}
Use compile time weaving, see for plugin example at: https://github.com/avner-levy/minimal_spring_hibernate_maven_setup/blob/master/pom.xml
The following combination of annotation and Spring config works for me thanks to notes above by Tobias/Willie/Eric:
Class:
package com.abc
#Configurable
#Aspect
public class MyAspect {
#Autowired
protected SomeType someAutoWiredField;
}
XML:
<context:spring-configured />
<context:component-scan base-package="com.abc" />
#Configurable(autowire = Autowire.BY_TYPE)
Add this annotation to your Aspectj class. Then it will be handled by Spring IOC.
For Spring Boot using #Autowired in #Aspect,
my way is using spring.factories configuration file
create a file named spring.factories in src/main/resources
the file content is as following
org.springframework.boot.autoconfigure.EnableAutoConfiguration=pack.age.to.YourAspect,pack.age.to.YourDAO

Spring: Autowired is null in ejb class

I have the following situation:
#Controller
public class myController {
#Autowired
private IProxy service;
public ModelAndView init(HttpServletRequest request, HttpServletResponse response) throws Exception {
List<String> list = service.getName();
}
}
Then my Service is define as follow:
public interface IProxy {
public List<String> getName();
}
Proxy class is responsible for the lookup to the remote bean
#Service("service")
public class Proxy implements IProxy {
...
public List<String> getName() {
return myClass.getName();
}
And the implementation is the following:
#Interceptors(interceptor.class)
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
#PersistenceContext(unitName = "db")
private EntityManager em;
#Resource
private SessionContext sctx;
#Autowired
public IMyRepo myRepo;
#Override
public List<String> getName() {
try {
return myRepo.getName(em);
}
catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
finally {}
}
So, the problem is that here myRepo is null. I don't know why because IMyRepo and his implementation are always located within the path scanned by Spring.
Just one clarification: MyRepo class that implements IMyRepo is annotated with #Repository.
Any idea?
you can inject spring beans in EJB using Spring interceptors, as explained here in the official documentation. Basically you'll need to adjust your class as follows:
// added the SpringBeanAutowiringInterceptor class
#Interceptors({ interceptor.class, SpringBeanAutowiringInterceptor.class })
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
// your code
}
You'll also need to define the context location in a beanRefContext.xml file (with your own application context file):
application-context.xml version
<bean id="context"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>application-context.xml</value>
</list>
</constructor-arg>
</bean>
Java Configuration version:
<bean id="context"
class="org.springframework.context.annotation.AnnotationConfigApplicationContext">
<constructor-arg>
<list>
<value type="java.lang.Class">com.your.app.Configuration</value>
</list>
</constructor-arg>
</bean>
Spring beans and EJB are two different things, you can't just inject a Spring bean in an EJB, because that EJB is no Spring bean, so Spring doesn't know there is a field which should be injected by Spring (unless you use some fancy AOP stuff, which can enable injection into non-Spring-managed beans).

How do I inject a bean in spring which is part of a class declared with #component tag

My spring config is set to use auto scanning for beans.
<context:annotation-config/>
<context:component-scan base-package="mypackage" />
I have a class that is declared with #Component
#Component
class A{
private InterfaceB b;
}
This InterfaceB is part of a jar file.
InterfaceBImpl implements InterfaceB{
// some contract here
}
I am getting an error from spring saying it cannot find a matching bean of type InterfaceB.
How can I inject that bean into the class?
private InterfaceB b in A has to be marked with #Autowired
But that doesn't enough, the InterfaceBImpl has to be a bean, too: or #Component, or as a <bean> in the xml config.
You have to declare a bean with the type B in your xml. Spring will automatically pick it up where you annotate a field with #Autowired.
Below is an example:
#Component
class A {
#Autowired
private B myB;
//other code
}
And in your xml:
<context:annotation-config/>
<context:component-scan base-package="mypackage" />
<bean id="myB" class="mypackage.InterfaceBImpl" />
Spring will see that A depends on B, looks in the context and sees that it has an implementation of B, which is InterfaceBImpl and inject it into A.
If you have control over the sources of InterfaceBImpl, add a #Component annotation to make Spring creating a bean be available for auto wiring.
If InterfaceBImpl cannot be changed, you can 1) extend it and annotate the extension or 2) you can create a configuration creating the bean:
1)
#Component
class MyInterfaceBImpl extends InterfaceBImpl {
}
2)
#Configuration
class MyAdditinalBeans {
#Bean
public InterfaceB interfaceB() {
return new InterfaceBImpl();
}
}

Spring DI Unsatisfied dependency expressed

applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.pomkine.pottyauth.domain.User"/>
<bean id="userdao" class="com.pomkine.pottyauth.persistance.GaeUserDao"/>
<bean id="userservice" class="com.pomkine.pottyauth.service.UserServiceImpl">
<constructor-arg ref="userdao"/>
</bean>
</beans>
Controller:
#Controller
public class RosterController {
private UserService userService;
#Inject
public RosterController(UserService userService){
this.userService=userService;
}
#RequestMapping(value = {"/userRoster"}, method = RequestMethod.GET)
public String showRosterPage(Map<String,Object> model){
model.put("users",userService.getAllUsers());
return "userRoster";
}
}
So I want UserService to be injected into my controller. But I'm getting the following exception:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rosterController' defined in file [S:\Coding\Idea_workspace\pottyAuth\target\pottyAuth-1.0\WEB-INF\classes\com\pomkine\pottyauth\mvc\RosterController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.pomkine.pottyauth.service.UserService]: : No matching bean of type [com.pomkine.pottyauth.service.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Here is my UserServiceImpl class:
public class UserServiceImpl implements UserService {
private UserDao dao;
public UserServiceImpl(UserDao dao){
this.dao=dao;
}
#Override
public User getUser(User user) {
return dao.getUser(user);
}
#Override
public void addUser(User user) {
dao.addUser(user);
}
#Override
public List getAllUsers() {
return dao.getAllUsers();
}
}
So I'm expecting Spring container to create UserServiceImlp bean and inject it into RosterController. But it seems that it cannot find UserServiceImpl bean.
What could be wrong?
UserServiceImpl is not implementing UserService
edit:
also I can't see
<context:component-scan base-package="">
Is this whole Spring configuration?
It means Spring couldnt find any bean of type UserService. Check your UserServiceImpl class.
Wondering why you are using both XML and annotation based approach to define beans? It will good if you stick to either of them.
EDIT:
Add #Component annotation to UserServiceImpl. So that Spring will come to know that it should create a object of UserServiceImpl
#Component
public class UserServiceImpl implements UserService
{
.....
}
and as #pawelccb have mentioned use
<context:component-scan base-package="your.base.package">
in Spring config file.
Check this link for details.

Spring3's #Configuration cannot #Inject component-scanned beans

This is my app.xml :
<context:component-scan base-package="destiny.web" />
<context:annotation-config/>
And there is a Dao(interface) , and DaoImpl (annotated with #Repository) inside destiny.web package.
There is another Spring3's destiny.web.AppConfig class :
#Configuration
public class AppConfig
{
#Inject
private Dao daoImpl
public AppConfig()
{
System.out.println("dao = " + daoImpl);
}
}
It prints 'null' , why ?
I am sure all these beans/configuration/repositories are scanned. But it seems #Configuration doesn't know other scanned beans . Did I miss anything ?
I try to solve it by #ImportResource :
#Configuration
#ImportResource("classpath:app.xml")
public class AppConfig
But it seems causing cyclic bean scan and throws this exception :
{main} org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Only one AsyncAnnotationBeanPostProcessor may exist within the context.
Offending resource: class path resource [app.xml]
How to solve it ?
Thanks.
Spring will invoke constructor firstly before inject / autowiring the other component. therefore your dao is null while you print at the constructor, because the dao still not injected yet.
Have a try to create test application for your configapp.
public class Main {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("stackoverflow.xml");
AppConfig appConfig = context.getBean(AppConfig.class);
appConfig.getConfig("smtp.host");
}
}
have you tried it also with the annotation #Autowired instead of #Inject?

Resources