I'd like to create a Runnable in my spring configuration for providing to a ScheduledExecutorService bean. This Runnable should call a function on an existing bean. I can't figure out how to do this in Spring. This is what the equivalent code looks like:
private Runnable updater = new Runnable() {
public void run() {
thing.update();
}
};
Spring XML can only define beans from concrete classes. Runnable is an interface, not a concrete class.
You can write a concrete class that does what you want:
public class ThingUpdatingRunnable implements Runnable {
private final Thing thing;
public ThingUpdatingRunnable(Thing thing) {
this.thing = thing;
}
#Override
public void run() {
thing.update();
}
}
... and define it as a bean in the normal way:
<bean id = "thingUpdater" class = "org.me.ThingUpdatingRunnable">
<constructor-argument ref="thing"/>
</bean>
... but you should probably get into configuring Spring through annotated Java - most Spring developers now prefer this to XML:
#Configuration
public class ThingUpdaterConfiguration {
#Bean
public Runnable thingUpdater(Thing thing) {
return new Runnable() {
public void run() {
thing.update();
}
}
}
}
(Or with Java 8:)
#Bean
public Runnable thingUpdater(Thing thing) {
return () -> thing.update();
}
Related
Want to clear the thread contex post execution of the functions annotated with #Scheduled in spring boot
Usage
#Scheduled(fixedDelayString = "10000")
publi void doSomething() {
}
Config for scheduled thread pool
#Bean(destroyMethod = "shutdownNow")
public ScheduledExecutorService scheduledExecutorService() {
return Executors.newScheduledThreadPool(5);
}
Have created a simple decorator to solve the same
package com.demo.decorator;
import com.demo.utils.GeneralUtils;
import org.springframework.core.task.TaskDecorator;
public class ThreadContextDecorator implements TaskDecorator {
#Override
public Runnable decorate(Runnable runnable) {
return () -> {
try {
runnable.run();
} finally {
GeneralUtils.clearContext();
}
};
}
}
Not sure how to add it in bean of ScheduledExecutorService
Let's say I have a custom ConstraintValidator:
public class FooValidator implements ConstraintValidator<ValidFoo, String> {
#Override
public void initialize(final ValidFoo foo) {
// No-op
}
#Override
public boolean isValid(final String foo, final ConstraintValidatorContext context) {
}
}
I'd like to be able to initialize this class by passing some configuration from the ServiceConfiguration in Dropwizard run or initialize.
Is this possible?
First, it's worth noting that the upcoming Dropwizard 2.0.0 release has built in support for this
For now, the process is a bit involved. You basically want to re-bootstrap the Hibernate validation but with a custom constraint validator factory that would support injection.
It's gonna involve about 4 custom classes, so bear with me. Here goes:
First, we start by registering a custom feature to wrap this functionality, into our Application class:
public void run(MainConfiguration config, Environment environment) throws Exception {
// ...
environment.jersey().register(InjectingValidationFeature.class);
}
Now we define the feature: InjectingValidationFeature - it basically registers our custom implementations within the service container:
public class InjectingValidationFeature implements Feature {
#Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder() {
#Override
protected void configure() {
bindFactory(ValidatorFactory.class).to(Validator.class).in(Singleton.class);
bind(InjectingConfiguredValidator.class).to(ConfiguredValidator.class).in(Singleton.class);
bind(InjectingConstraintValidatorFactory.class).to(ConstraintValidatorFactory.class).in(Singleton.class);
}
});
return true;
}
}
Now we define those classes that we are registering above. Let's start with the core piece, the InjectingConstraintValidatorFactory which is what Hibernate Validator will actually use to create the constraint validators. Note that because we are registering them in the container, we can actually start injecting stuff already, here is our custom ConstraintValidatorFactory making use of the service locator to make dependency injection possible:
public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
private final ServiceLocator serviceLocator;
#Inject
public InjectingConstraintValidatorFactory(ServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
#Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
return this.serviceLocator.createAndInitialize(key);
}
#Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
this.serviceLocator.preDestroy(instance);
}
}
Now our factory for the central javax.validation.Validator interface:
public class ValidatorFactory implements Factory<Validator> {
private final ConstraintValidatorFactory constraintValidatorFactory;
#Inject
public ValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
this.constraintValidatorFactory = constraintValidatorFactory;
}
#Override
public Validator provide() {
return Validation.byDefaultProvider().configure().constraintValidatorFactory(
this.constraintValidatorFactory).buildValidatorFactory()
.getValidator();
}
#Override
public void dispose(Validator instance) {
// Nothing
}
}
And finally, our InjectingConfiguredValidator, notice how it's just using DropwizardConfiguredValidator but with an #Inject which would allow us to receive the validator from our ValidatorFactory above:
public class InjectingConfiguredValidator extends DropwizardConfiguredValidator {
#Inject
public InjectingConfiguredValidator(Validator validator) {
super(validator);
}
}
That's it. With the above, we managed to both register an injection-aware Validator with Jersey and also into our service container so you can also #Inject Validator anywhere and use it however you like.
I want to implement the GoF Observer Design Pattern using Spring Boot without Spring Events. Code sample:
#Component
public class MyObservable extends java.util.Observable {
void myObservableMethod(Object obj){
notifyObservers(obj);
}
}
#Component
public class MyObserver implements java.util.Observer{
#Override
public void update(java.util.Observable observable, Object obj) {
System.out.println(obj.toString());
}
}
Are the java.util classes a good implementation for that pattern ?
How can I register the observer with the observable , and still able to use Spring Depedency Injection?
Where I can call myObserver.accept(myObservable); ?
#Autowired
MyObservable myObservable;
#Autowired
MyObserver myObservable;
myObserver.accept(myObservable); //??
Are the java.util classes a good implementation for that pattern ?
The GoF pattern and the java implementation of it are a bit dated and have some issues.
It really depends on the problem you are trying to solve, but it might be suitable if your application doesn’t make massive use of events and you don’t want to introduce something like spring events or RxJava.
How can I register the observer with the observable , and still able
to use Spring Depedency Injection? Where I can call
myObserver.accept(myObservable); ?
See the below example of how you can define an Observable some observers, wire them up and finally send some events to them.
#SpringBootApplication
public class ObserverApplication {
public static void main(String[] args) {
try(ConfigurableApplicationContext ctx = SpringApplication.run(ObserverApplication.class, args)){
Observable observable = ctx.getBean(Observable.class);
observable.notifyObservers("Hello");
}
}
#Bean
public Observable myObservable(){
return new MyObservable();
}
#Bean
MyObserver observer1(){
return new MyObserver(1);
}
#Bean
MyObserver observer2(){
return new MyObserver(2);
}
#Autowired
public void configureObservers(Observable myObservable, MyObserver observer1, MyObserver observer2){
myObservable.addObserver(observer1);
myObservable.addObserver(observer2);
}
static class MyObserver implements Observer {
int id;
public MyObserver(int id) {
this.id = id;
}
#Override
public void update(Observable o, Object arg) {
System.out.println("Observer: " + id + ", Received object: " + arg);
}
}
static class MyObservable extends Observable {
#Override
public void notifyObservers(Object arg){
this.setChanged();
super.notifyObservers(arg);
}
}
}
I am developing a REST API using Jersey 2 and I need some of my classes to be instantiated on start up and not just when some resource request triggers it.
So what I am asking is: how do I achieve that an instance of SomethingImpl defined below here is created on server start up and not just when someone hits the something resource? In Guice I would use .asEagerSingleton().
Application:
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(new AbstractBinder() {
#Override
protected void configure() {
bind(" else").to(String.class);
bind(SomethingImpl.class).to(Something.class).in(Singleton.class);
}
});
register(SomeResource.class);
}
}
Something:
public interface Something {
String something();
}
public class SomethingImpl implements Something {
#Inject
public SomethingImpl(final String something) {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
System.out.println(something() + something);
try {
Thread.sleep(4000);
} catch (final InterruptedException e) {
break;
}
}
}
}).start();
}
#Override
public String something() {
return "Something";
}
}
Some resource:
#Path("/")
public class SomeResource {
private final Something something;
#Inject
public SomeResource(final Something something) {
this.something = something;
}
#GET
#Path("something")
public String something() {
return something.something();
}
}
In a later release of hk2 than is integrated with Jersey (but which will be integrated soon) you can have services that are marked #Immediate. These basically get started as soon as they are added to hk2. However, in order to make it work you will have to add the Immediate context to the system (e.g. https://hk2.java.net/2.2.0-b27/apidocs/org/glassfish/hk2/utilities/ServiceLocatorUtilities.html#enableImmediateScope%28org.glassfish.hk2.api.ServiceLocator%29)
It would be a good idea to lobby with the Jersey team to have this scope/context pair enabled by default (they already enable things like PerThread scope)
I have created this issue: https://java.net/jira/browse/JERSEY-2291 to request that Jersey enable #Immediate services by default
Write an implementation of a javax.servlet.ServletContextListener and add that listener to your web xml.
http://www.mkyong.com/servlet/what-is-listener-servletcontextlistener-example/
Besides what msknapp said, you can also use #WebListener for the servlet context listener so that you don't have to add the listener to web.xml. Then your listener will look like
#WebListener
public class SomethingListener implements ServletContextListener {
#Inject
private final Something something;
#Override
public void contextInitialized(ServletContextEvent sce) {
//put code about something here
}
}
I've a little experience in Spring. And I wondering about the amount of callbacks in Spring Context/Bean Lifecycle. I've never used them, and can imaging situations in which the most of them are needed.
My question is: can you provide for each callback at least one example of usage? Means situations when you need that callback.
Conext callbacks:
Bean callbacks:
P.S.:
It is clear for me when majority of callbacks are calling, or what one or another implementation of ApplicationContext was written for. But I can't figure out why someone may want to profit from that callback\implementation. For example:
AbstractRefreshableApplicationContext is using to change bean configurations on fly. But Why? In which situation I may want to change bean's configuration on fly?
afterPropertiesSet callback, obviously is invoked after all bean's properties are setted :) But why I should know about that, and when I should (may want) use it?
can you provide for each callback at least one example of usage?
Look at the javadoc for each of the interfaces, check any of the implementing classes for their purpose and look up their source code for their implementation.
A typical bean definition would be
<bean id="someBean" class="com.example.beans.SomeBean">
<property name="someProperty" value="42" />
<property name="other" value="I will always love you." />
</bean>
with a class like
public class SomeBean {
private String someProperty;
private String other;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public void setOther(String other) {
this.other = other;
}
}
But some times you have classes where you need to perform some logic based on the properties set
public class SomeBean {
private String someProperty;
private String other;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public void setOther(String other) {
this.other = other;
}
public void init() {
Thread thread = new Thread(new Runnable() {
public void run() {
// for example
// send the two property values to some external service
}
});
thread.start();
}
}
This logic can only be performed after the properties have been set. In that case, you can have your class implement the InitializingBean interface (old school)
public class SomeBean implements InitializingBean {
private String someProperty;
private String other;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public void setOther(String other) {
this.other = other;
}
public void init() {
Thread thread = new Thread(new Runnable() {
public void run() {
// for example
// send the two property values to some external service
}
});
thread.start();
}
public void afterPropertiesSet() throws Exception {
init();
}
}
Or annotate it with #PostConstruct (new school)
public class SomeBean implements InitializingBean {
private String someProperty;
private String other;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public void setOther(String other) {
this.other = other;
}
#PostConstruct
public void init() {
Thread thread = new Thread(new Runnable() {
public void run() {
// for example
// send the two property values to some external service
}
});
thread.start();
}
}
This is just an example. The InitializingBean interface is often used along with the FactoryBean interface. It helps to initialize the factory before it produces an object. For more example, see the javadoc of both of those interfaces and look up the source code of the various implementing classes. Do the same for the other *Aware interfaces.
As for AbstractRefreshableApplicationContext, some times you need to refresh() your ApplicationContext. This can happen because you want to reload an XML configuration or because your environment has changed, but you don't want to stop/re-start the application.
1. BeanFactoryPostProcessor:
I give this example as I see this answer: https://stackoverflow.com/a/2349891/4251461
He initially chose BeanFactory for use in integration/performance tests since He didn't want to load the entire application for testing isolated beans. However, He think BeanFactory doesn't support classpath XML configuration. So BeanFactory and ApplicationContext each provide a crucial feature I wanted, but neither did both.
He implements his own ApplicationContext which extends ClassPathXmlApplicationContext.
Here he could use BFPP instead of custom ApplicationContext.
public class LazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
bd.setLazyInit(true);
}
}
}
configure it in spring container like other regular beans:
<bean class="com.example.LazyInitBeanFactoryPostProcessor" />
You can also see the source of PropertyPlaceholderConfigurer and PropertyOverrideConfigurer in spring.
2. InitializingBean:
As Sotirios Delimanolis said: The InitializingBean interface is often used along with the FactoryBean interface. It helps to initialize the factory before it produces an object.
Here is an example.
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import java.security.MessageDigest;
public class SampleDigesterFactory implements FactoryBean<MessageDigest>, InitializingBean {
MessageDigest messageDigest;
String algorithmName = "MD5";
public MessageDigest getObject() throws Exception {
return messageDigest;
}
public Class<?> getObjectType() {
return MessageDigest.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
messageDigest = MessageDigest.getInstance(algorithmName);
}
public String getAlgorithmName() {
return algorithmName;
}
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
}
import java.security.MessageDigest;
public class SampleDigester {
private MessageDigest messageDigest;
public void digestMessage(String message) {
System.out.println("digest message:" + message);
System.out.println("result: " + messageDigest.digest(message.getBytes()));
}
public MessageDigest getMessageDigest() {
return messageDigest;
}
public void setMessageDigest(MessageDigest messageDigest) {
this.messageDigest = messageDigest;
}
}
configure beans in spring container:
<bean id="messageDigesterFactoryMD5" class="com.example.SampleDigesterFactory" />
<bean id="messageDigesterFactorySHA1" class="com.example.SampleDigesterFactory" p:algorithmName="SHA1" />
<bean id="sampleDigesterMD5" class="com.example.SampleDigester" p:messageDigest-ref="messageDigesterFactoryMD5" />
<bean id="sampleDigesterSHA1" class="com.example.SampleDigester" p:messageDigest-ref="messageDigesterFactorySHA1" />
Test it:
SampleDigester sampleDigesterMD5 = context.getBean("sampleDigesterMD5", SampleDigester.class);
SampleDigester sampleDigesterSHA1 = context.getBean("sampleDigesterSHA1", SampleDigester.class);
sampleDigesterMD5.digestMessage("Hello World!");
sampleDigesterSHA1.digestMessage("Hello World!");
The output is:
digest message:Hello World!
result: [B#19d02cb
digest message:Hello World!
result: [B#1753b6d
The spring reference says:
The FactoryBeanconcept and interface is used in a number of places within the Spring Framework;more than 50 implementations of the FactoryBeaninterface ship with Spring itself.
3. BeanPostProcessor:
You can refer to source of RequiredAnnotationBeanPostProcessor in spring.
a BeanPostProcessorimplementation that ships with the Spring distribution which ensures that JavaBean properties on beans that are marked with an (arbitrary) annotation are actually (configured to be) dependency-injected with a value.