I have a class defined like this:
public class MyClass extends SimpleChannelInboundHandler<DataFrame<ByteBuf>> implements ApplicationEventPublisherAware
(SimpleChannelInboundHandler is an io.netty class.)
Then, in my xml file I define the MyClass like this:
<bean id="MyClass" class="com.mypackage.MyClass" />
According to the documentation:
At configuration time, the Spring container will detect that
EmailService implements ApplicationEventPublisherAware and will
automatically call setApplicationEventPublisher().
But it's null when I run this.
Any ideas why?
Thanks
A common usage pattern for ApplicationEventPublisherAware looks like this:
package example;
import org.springframework.stereotype.*;
import org.springframework.context.*;
#Component
public class MyBean implements ApplicationEventPublisherAware {
ApplicationEventPublisher applicationEventPublisher;
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("publisher: " + applicationEventPublisher);
this.applicationEventPublisher = applicationEventPublisher;
}
... (use applicationEventPublisher in methods)
}
You just need to make sure the bean is really added to the context via component scan / configuration / <bean> tag, try to inject it into another bean to check that.
You should use the getBean method of ApplicationContext to get an instance of MyClass instead of initializing by yourself using the new keyword. So that Spring Container could set the ApplicationEventPublisher.
Related
Want put a class in a HashMap. For that I have created a Bean with #Service. This is it:
#Service
public class ServiceManagerImpl implements ServiceManager {
#Override
public void registerService() {
// registerService will put this in the HashMap!
dispatcher.registerService("serviceList", getServiceListImpl());
}
#Bean
public BusinessService getServiceListImpl() {
return new ServiceListManager();
}
}
Is this the right way to make something like this?
Move your bean definition from a class annotated with #Service to a configuration class annotated with #Configuration (or at least move to your main class which has #SpringBootApplication annotation, if you have). Then Autowire that bean here in the Service class. `
#Autowired BusinessService businessService
take a look here Where to put #Bean in Spring Boot?
I am new to Spring. I have at work in spring-config.xml this :
<bean id="statusEmailSender" class="my.package.email.StatusEmailSenderImpl">
<property name="mailSender" ref="mailSender"/>
<property name="templateMessage" ref="templateMessage"/>
</bean>
In some classes already defined I see something like this:
#Autowired
private StatusEmailSender statusEmailSender;
And it works. When I do it in my own class, I get a NullPointerException.
I know the reason: I am creating my class with new():
return new EmailAction(config,logger);
My class looks like this:
public class EmailAction{
#Autowired
StatusEmailSender statusEmailSender;
public EmailAction(...)
{
...
}
}
Do you know how I can get around this? This is legacy code, and it's extremely difficult to get around the new EmailAction() call.
You want use a spring bean inside a non-spring class(legacy code). In order to do that you need to make the Spring's ApplicationContext (which holds BeanFactory where spring beans are residing) available to legacy code.
For that you need to create a spring bean something like:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
and define this bean inside your Spring configuration file (or if you are using annotation driven, annotate bean with #Component)
<bean id="springContext" class="com.util.SpringContext />
Since SpringContext exposes a static method, the legacy code can access it.for example if the legacy code needs spring bean EmailAction, call like:
EmailAction emailAction= (EmailAction)SpringContext.getApplicationContext.getBean(EmailAction.class);
now the emailAction will contain all its dependencies set.
Why don't you just autowire your EmailAction class when you need it?
EmailAction.java:
#Component
public class EmailAction{
// ...
}
WhereYouNeedIt.java:
public class WhereYouNeedIt{
#Autowired
EmailAction emailAction;
// access emailAction here
}
i am really confused with spring annotations.
where to use # Autowired, where class is # Bean or # Component,
i understand we cannot use
Example example=new Example("String");
in Spring
but how alone
#Autowired
Example example;
will solve the purpose?
what about Example Constructor ,how spring will provide String value to Example Constructor?
i went through one of the article but it does not make much sense to me.
it would be great if some one can give me just brief and simple explanation.
Spring doesn't say you can't do Example example = new Example("String"); That is still perfectly legal if Example does not need to be a singleton bean. Where #Autowired and #Bean come into play is when you want to instantiate a class as a singleton. In Spring, any bean you annotate with #Service, #Component or #Repository would get automatically registered as a singleton bean as long as your component scanning is setup correctly. The option of using #Bean allows you to define these singletons without annotating the classes explicitly. Instead you would create a class, annotate it with #Configuration and within that class, define one or more #Bean definitions.
So instead of
#Component
public class MyService {
public MyService() {}
}
You could have
public class MyService {
public MyService() {}
}
#Configuration
public class Application {
#Bean
public MyService myService() {
return new MyService();
}
#Autowired
#Bean
public MyOtherService myOtherService(MyService myService) {
return new MyOtherService();
}
}
The trade-off is having your beans defined in one place vs annotating individual classes. I typically use both depending on what I need.
You will first define a bean of type example:
<beans>
<bean name="example" class="Example">
<constructor-arg value="String">
</bean>
</beans>
or in Java code as:
#Bean
public Example example() {
return new Example("String");
}
Now when you use #Autowired the spring container will inject the bean created above into the parent bean.
Default constructor + #Component - Annotation is enough to get #Autowired work:
#Component
public class Example {
public Example(){
this.str = "string";
}
}
You should never instantiate a concrete implementation via #Bean declaration. Always do something like this:
public interface MyApiInterface{
void doSomeOperation();
}
#Component
public class MyApiV1 implements MyApiInterface {
public void doSomeOperation() {...}
}
And now you can use it in your code:
#Autowired
private MyApiInterface _api; // spring will AUTOmaticaly find the implementation
In my jsp, I have a custom tag
<ex:SelfService />
which intrun calls the java class
public class SelfServiceClass extends SimpleTagSupport{
#Autowired
private ReloadablePropertyManagerImpl reloadableProperty;
public ReloadablePropertyManagerImpl getReloadableProperty() {
return reloadableProperty;
}
public void setReloadableProperty(
ReloadablePropertyManagerImpl reloadableProperty) {
this.reloadableProperty = reloadableProperty;
}
public void doTag() throws IOException {
JspWriter out = getJspContext().getOut();
out.println(getReloadableProperty().getPropertyValue("print.service"));
}
}
And in my spring.xml I have configured the bean,
<bean id="reloadableProperty" class="com.testing.portal.util.ReloadablePropertyManagerImpl" />
But I am getting null pointer exception when I call getPropertyValue() on reloadableProperty object.
Any help will be much appreciated.
Since your class is not managed by Spring you have to load the ReloadablePropertyManagerImpl from the application context by yourself. In order to do so you should create a class which implements ApplicationContextAware with a static getter for the context.
See more in this sample.
Is Spring aware of SelfServiceClass class? It has to be. You either annotate it with #Component or it is returned by a #Configuration as a #Bean or include it as you did with reloadebleProperty in the xml, i.e.: make it a spring managed bean
I am using Spring 3.0 for my project, I am having a class MySingletonClass, it is singleton as below :
//#Component("mySingletonClass")
public class MySingletonClass {
private static MySingletonClass obj = new MySingletonClass();
public static MySingletonClass getSingleObj() {
return obj;
}
}
spring xml bean configuration for this class is as below :
<bean id="mySingletonClass" class="app.MySingletonClass" factory-method="getSingleObj" />
I was trying to remove bean configuration and use annotation. how do I write annotation for factory method?
Thanks in advance !!
Spring creates instances like singleton by default. You can just do.
#Component("mySingletonClass")
public class MySingletonClass {
}
And if you don't change scope your component is singleton.
Spring component's are automatically created as Singletons.
Declare the annotation #Controller on the class
#Controller
public class MySingletonClass {
}
Then in your Spring Config file, declare like:
<bean id="mySingleton" class="com.package.MySingletonClass">
Then to use in another class you can use Autowiring or Setter/Constructor dependency injection.
#Component
public class OtherClass {
#Autowired
private MySingletonClass mySingleton;
}