I am trying to autowire a class into a WebSocketServlet in the following way:
#Configurable(autowire=Autowire.BY_TYPE)
public class MyServlet extends WebSocketServlet {
#Autowired
public MyClass field;
// etc...
}
Here's what my configuration looks like:
<context:annotation-config />
<context:component-scan base-package="org.*" />
<bean id="config" class="org.*.MyClass">
<!-- a bunch of properties -->
</bean>
Note that autowire used to work just fine as long as I was in a Spring #Controller. I had to step out of that because i don't know how to map a WebSocketsServlet to a method of the #Controller as you do with regular servlets.
Any idea what I might be missing?
In order to use #Configurable, you need to have these line in tour context:
<context:load-time-weaver aspectj-weaving="true"/>
<context:spring-configured/>
<context:annotation-config />
<context:component-scan base-package="org.*" />
In addition, I think you must reference spring-aspect in the Import-Library section of your Manifest.
I didn't succeed to make it work, there is a post on this in the Virgo forum at Eclipse.
If you succeed, let me know how ;)
Getting rid of #Configurable and doing the following in the servlet init method does the trick:
#Override
public void init() throws ServletException {
super.init();
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
As per the spring documentation
Externalized values may be looked up by injecting the Spring Environment into a #Configuration class using the #Autowired or the #Inject annotation:
#Configuration
public class AppConfig {
#Inject Environment env;
#Bean
public MyBean myBean() {
MyBean myBean = new MyBean();
myBean.setName(env.getProperty("bean.name"));
return myBean;
}
}
Related
I have some problem when autowired my config bean.
#Configuration
#ImportResource("classpath:/spring-config.xml")
public class MailConfig {
private JavaMailSenderImpl impl;
#Autowired
public MailConfig(JavaMailSenderImpl impl) {
this.impl = impl;
}
...
Spring say that:
Could not autowire. There is more than one bean of 'JavaMailSenderImpl' typr.
Beans: 1)mailSender (MailSenderJndiConfiguration.class)
2)mailSenderBean (spring-config.xml)
I don't use jndi bean. And have no idea about it in this app.
How to ignore Jndi bean? Or maybe simpler config Jndi bean instead mine?
Thanks.
---------------------------------RESOLVED------------------------------
I add property in xml
<qualifier value="main" />
And change code
private JavaMailSenderImpl impl;
#Autowired
public MailConfig(#Qualifier("main")JavaMailSenderImpl impl) {
this.impl = impl;
}
Please autowire Interface instead of Implementation
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
but in your class replace JavaMailSenderImpl with JavaMailSender
I am working on some legacy code that uses spring bean definitions on xml.
The module I am building uses annotations.
The problem is that sometimes I need to override a legacy bean definition so I need to put my beans on xml as well.
I have the following:
public class BeanIAmOverriding {
private MyAnnotatedBean bean;
}
#Component
public class MyAnnotatedBean {
private Repository repo;
}
#Repository
public class Repository {
#Transational
public Something find(...)
}
Xml file:
<bean id="bean" class="a.b.c.BeanIAmOverriding"/>
In this scenario, my repository does NOT get proxied with the transactional aspec.
I even tried just aliasing it but the same thing happens.
My current workaround is implementind BeanFactoryAware.
Do you have any better ideas?
EDIT:
Let me clarify.
I do know dependency injection, I just ommited some configuration I didn't think would be that relevant given the context, but here they are.
I would like to do something like:
<bean id="bean" class="a.b.c.BeanIAmOverriding">
<constructor-arg index="0" ref="myAnnotatedBean"/>
</bean>
That doesn't work. When I do that my Repository does not get proxied by the transactional aspect.
So I have this workaround:
public class BeanIAmOverriding implements BeanFactoryAware{
//private MyAnnotatedBean bean;
private BeanFactory beanFactory;
public void something(){
beanFactory.getBean(MyAnnotatedBean.class).doSomething();
}
#Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
Like I said in my comment, the problem is that you're not injecting the 'BeanIAmOverriding.bean', as spring doesn't know it has to inject it! Try the following (I'm not 100% sure if the following will work, as it's been a long time since I worked on a project that used a mix of 'legacy' xml and annotations).
public class BeanIAmOverriding {
private MyAnnotatedBean bean;
#Autowired
public BeanIAmOverriding(MyAnnotatedBean bean) {
this.bean = bean;
}
}
The #Autowired annotation will tell spring how to instantiate the class. Spring will then take the instance of MyAnnotatedBean and inject it in the constructor.
I'm not sure how experienced you are with Spring, but I would recommend you to read a bit the section on dependency injection.
I have an aspect which creates by load-time weaving mechanism. But I need to inject my service in it, so it aspect must be created by spring.
My aspect looks like this :
#Aspect
public class SomeAspect {
#Inject
private SomeService someService;
#Before("some_pointcut_here")
public void doInterception() {
//...call service here
}
}
I can do it with xml:
<bean id="myAspect" class="foo.bar.SomeAspect" factory-method="aspectOf" />
So the question is how to achieve the same with spring java config. Any suggestions will be appreciated. Thanks
Edit
I annotate my aspect with #Component and it works. It strange for me because in case of xml config dependency injection doesn't worked in my case, but it works for java configuration
#Bean
public SomeAspect someAspect() {
return org.aspectj.lang.Aspects.aspectOf(SomeAspect.class);
}
ISSUE:
I am trying to inject a service into a bean but the service instance is always null.
BACKGROUND:
I have two beans one called from the other. This is how they are defined in XML config:
<context:annotation-config />
<bean class="com.test.MyBeanImpl" name="myBean"/>
<bean id="myService" class="com.test.MyServiceImpl" />
and the beans are implemented like so:
MyServiceImpl.java
class MyServiceImpl implements MyService {
public void getString() {
return "Hello World";
}
}
MyBeanImpl.java
#Component
class MyBeanImpl implements MyBean, SomeOtherBean1, SomeOtherBean2 {
#Resource(name="myBean")
private MyService myService;
public MyBeanImpl() {}
}
QUESTIONS:
Is there some reason related to the fact that my bean implements 3 interfaces that is preventing the Service being injected? If not what other factors could be effecting it?
as you are using annotations Just mark your service class with #Service annotation and use #Autowired annotation to get the instance of your service class
MyServiceImpl.java
package com.mypackage.service;
#Service
class MyServiceImpl implements MyService {
public void getString() {
return "Hello World";
}
}
MyBeanImpl.java
#Component
class MyBeanImpl implements MyBean, SomeOtherBean1, SomeOtherBean2 {
#Autowired
private MyService myService;
public MyBeanImpl() {}
}
also make sure you mention your package name in <context:component-scan /> element in your dispatcher file as
<context:annotation-config />
<context:component-scan base-package="com.mypackage" />
hope this will solve your problem
Make sure the bean you are injecting MyService into is a bean.
/* This must be a bean, either use #Component or place in configuration file */
#Component
public class SomeClass{
#Resource
private MyService myService;
}
Also make sure that within your configuration you have specified that the application uses annotation-based configuration using:
<context:annotation-config/>
Since your using multiple interfaces it may be best to qualify the bean with a name:
<bean class="com.test.MyBeanImpl" name="myBean" />
Then specify the name element on the #Resource annotation
#Resource(name="myBean")
private MyService myService;
Here is a Github Gist that explains these concepts.
I created a custom annotation for logging following the example in this blog post almost exactly. The main difference that I can see is my LoggerInjector is annotated with #Component.
The annotation works great and I get a non-null Logger instance everywhere except in one case: when I try to log in a method annotated with #Autowired.
For example:
#Repository
public class MyDao
{
#AutowiredLogger
private Logger _logger;
private JdbcTemplate _jt;
#Autowired
public void setDatasource(DataSource ds)
{
_logger.debug("Entering setDs")
_jt = new JdbcTemplate(ds);
_logger.debut("Exiting setDs);
}
}
A NullPointerException is thrown on the first _logger.debug() line.
A snippet from applicationContext.xml:
<mvc:annotation-driven />
<context:component-scan base-package="my.package" />
A snippet from dispatch-servlet.xml:
<mvc:annotation-driven />
<context:component-scan base-package="my.package">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Repository" />
</context:component-scan>
How can I have my #AutowiredLogger injected before the #Autowired methods are run?
I don't think you can control which component gets autowired first. An alternate solution is to use InitializingBean to configure the class after everything has been set.
You could something like
#Override
void afterPropertiesSet() {
_logger.debug("Entering setDs")
_jt = new JdbcTemplate(ds);
_logger.debut("Exiting setDs);
}