Get new instance of a spring bean - java

I have an interface called MyInterface. The class that implements MyInterface (lets call it MyImplClass) also implements the Runnable interface so i can use it to instantiate threads. This is my code now.
for (OtherClass obj : someList) {
MyInterface myInter = new MyImplClass(obj);
Thread t = new Thread(myInter);
t.start();
}
What i want to do is to declare the implementing class in my ApplicationContext.xml and get a new instance for each iteration. So my code will look something like this:
for (OtherClass obj : someList) {
MyInterface myInter = // getting the implementation from elsewhere
Thread t = new Thread(myInter);
t.start();
}
I want to still keep the IoC pattern if possible.
How can i do so?
Thanks

You can try factory pattern with spring scope prototype like below. Define a Abstract Factory Class which will give you MyInterface object
public abstract class MyInterfaceFactoryImpl implements MyInterfaceFactory {
#Override
public abstract MyInterface getMyInterface();
}
Then define the Spring bean.xml file as below. Please note myinterface bean is defined as prototype ( So it will always give you new instance).
<bean name="myinterface" class="com.xxx.MyInterfaceImpl" scope="prototype"/>
Then define the factorybean with factory method name.
<bean name="myinterfaceFactory" class="com.xxx.MyInterfaceFactoryImpl">
<lookup-method bean="myinterface" name="getMyInterface" />
</bean>
Now you can call myinterfaceFactory to get new instance.
for (OtherClass obj : someList) {
MyInterface myInter = myInterfaceFactory.getMyInterface();
Thread t = new Thread(myInter);
t.start();
}

Keep the spring configuration file, beans.xml in the root of the classpath.
Making scope=prototype, will result in different instances of bean for each getBean method invocation.
beans.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="myinterface" class="MyImplClass" scope="prototype"/>
</beans>
Similar way if you want Spring to return the same bean instance each time one is needed, you should declare the bean's scope attribute to be singleton.
Once the IoC container is initialized, you can retrieve your Spring beans. But make sure, you do the below only initialization only once.
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Then you can change your code as below.
for (OtherClass obj : someList) {
MyInterface myInter = (MyInterface ) context.getBean("myinterface");
Thread t = new Thread(myInter);
t.start();
}

Given the context you provided in your comment to me, I would suggest you don't have the MyImplClass instances created by Spring. Having this prototyped object instantiated by Spring provides no benefit from what I can tell.
The best way, in my opinion, to keep with the IoC pattern here would be to instead utilize a Spring managed Factory that produces instances of MyImplClass. Something along the lines of this:
public class MyInterfaceFactory {
public MyInterface newInstance(final OtherClass o) {
return new MyImplClass(o);
}
}
Depending on the usage needs, you can modify this factory's interface to return MyImplClass, or add some logic to return a different implementation of MyInterface.
I tend to think that Factories and IoC/DI work pretty well together, and your use case is a pretty good example of that.

Initial Note 1
Instead of creating and starting threads by hand, I would suggest to use a pool of threads that is externally configured, so that you can manage the number of threads that are created. If the size of someList is 1000, creating so many threads is inefficient. You should better use an executor backed by a pool of threads. Spring provides some implementations that can be used as spring beans configured with the task namespace, something like this:
<task:executor id="executor" queue-capacity="10" rejection-policy="CALLER_RUNS" />
queue-capacity is the max size of the threads pool. If that size is exceeded, the current thread will run the additional task, thus blocking the loop until another thread is freed (rejection-policy="CALLER_RUNS"). See the task:executor documentation, or define any ThreadPoolExecutor (spring or jdk-concurrent) with your own configuration.
Initial Note 2
If the only state that you intend to store in MyClassImpl is the item from the list, then you can forget the rest of the explanation below (except for the ThreadPool stuff), and directly use a singleton bean : remove the Runnable interface and its no-arg run() method, add a run(OtherClass obj) method and do something like this:
final MyInterface task = // get it from spring as a singleton
for (final OtherClass obj : someList) {
executor.execute(new Runnable() {
public void run() {task.run(obj);}
});
// jdk 8 : executor.execute(task::run);
}
If you plan to store some state inside MyClassImpl during the execution of run() (other than the processed object), go on reading. But you will still use the run(OtherClass obj) method instead of no-args run().
The basic idea is to get a different object for each running thread, based on some kind of model or prototype defined as a spring bean. In order to achieve this, just define the bean that you initially want to pass to each thread as a proxy that dispatches to an instance that is bound to the running thread. This means that the same instance of task is injected into each thread, and during the thread execution, the real task on which you invoke methods is bound to the current thread.
Main program
Since you are using the elements of the list to do your business, you will pass each element to its owning task.
public class Program {
#Resource private MyInterface task; // this is a proxy
#Resource private TaskExecutor executor;
public void executeConcurrently(List<OtherClass> someList) {
for (final OtherClass obj : someList) {
executor.execute(new Runnable() {
public void run() { task.run(obj); }
});
// jdk 8 : executor.execute(task::run);
}
}
}
We suppose that Program is a spring bean, thus the dependencies can be injected. If Program is not a spring bean, you will need to get the spring ApplicationContext from somewhere, then autowire Program (i.e. inject dependencies found in the ApplicationContext, based on annotations). Something like this (in the constructor) :
public Program(ApplicationContext ctx) {
ctx.getAutowireCapableBeanFactory().autowireBean(this);
}
Define the task
<bean id="taskTarget" class="MyImplClass" scope="prototype" autowire-candidate="false" />
<bean id="task" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean class="org.springframework.aop.target.ThreadLocalTargetSource">
<property name="targetBeanName" value="taskTarget"/>
<property name="targetClass" value="MyInterface"/>
</bean>
</property>
</bean>
taskTarget is where you define your business. This bean is defined as a prototype, as a new instance will be allocated to each thread. Thanks to this, you can even store state that depends on the run() parameter. This bean is never used directly by the application (thus autowire-candidate="false"), but it is used through the task bean. In executeConcurrently() above, the line task.run(obj) will actually be dispatched on one of the prototype taskTarget that was created by the proxy.

If you can determine at runtime which MyImplClass instance to use, you could list all implementations as beans in your context xml and #Autowire an array of type MyInterface to get all MyInterface implementors.
Given the following in the context xml:
<bean class="MyImplClass" p:somethingCaseSpecific="case1"/>
<bean class="MyImplClass" p:somethingCaseSpecific="case2"/>
Then a deceleration
#Autowire
MyInterface[] allInterfaceBeans;
will result in allInterfaceBeans containing both beans defined above.
If you wanted the logic for determining which implementation to use to be done at injection time, you could always #Autowire a setter method setAllInterfaceBeans(MyInterface[] allInterfaceBeans);.

First and foremost, we all know that by default spring container will create bean in singleton mode (if you don't explicitly specify the scope). As the name implies, singleton guarantee that everytime you call the bean, it will give you the same instance. Nevertheless, there's slightly differences between singleton in spring with the one singleton that mentioned by GoF. In Spring, the created instance will be restricted to the container (not JVM as we found in GoF).
Additionally, in spring, you can define two different bean instances of the same type but with different names and they will be two different instances created on the heap. But every time you reference one of those beans by name (ref= in a bean definition or getBean on the appContext), you get the same object every time. That is obviously different than the actual singleton pattern but similar in concept anyway.
Generally speaking, there are implications of using a singleton in a multi-threaded application (Spring singleton or actual singleton). Any state that you keep on these objects must account for the fact that multiple threads will access it. Usually, any state that exists will be set during instantiation via a setter or constructor argument. This category of Spring bean makes sense for long lived objects, thread-safe objects. If you want something thread specific and still desire spring to create the object, then prototype scope works.

Related

Spring does not call destroy method of singleton bean if same method is defined on prototype bean [duplicate]

I am new to the spring framework, started with some tutorials to learn it.
I have following files,
# MainProgram.java
package test.spring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainProgram {
public static void main(String[] args) {
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("Bean.xml");
HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
obj.setMessage("My message");
obj.getMessage();
context.registerShutdownHook();
}
}
# HelloSpring.java
package test.spring;
public class HelloSpring {
private String message;
public void setMessage(String message){
this.message = message;
System.out.println("Inside setMessage");
}
public void getMessage(){
System.out.println("Your Message : " + this.message);
}
public void xmlInit() {
System.out.println("xml configured initialize");
}
public void xmlDestroy() {
System.out.println("xml configured destroy");
}
}
# Bean.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-3.0.xsd">
<bean id="helloSpring" class="test.spring.HelloSpring"
scope="prototype" init-method="xmlInit" destroy-method="xmlDestroy">
</bean>
</beans>
When I take scope="singleton" my output is :
xml configured initialize
Inside setMessage
Your Message : My message
xml configured destroy
When I take scope="prototype" my output is :
xml configured initialize
Inside setMessage
Your Message : My message
xmlDestroy() method is called with singleton scope bean but not with prototype
kindly help me for the following ,
Is this correct? if so, what would be possible reasons?
Also I have some queries like,
what is difference or relation between
ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext
xmlDestroy() method is called with singleton scope bean but not with prototype because
Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the client and then has no further knowledge of that prototype instance. For releasing resources try to implement a custom bean post processor.
Unlike singleton beans where the spring container manages the complete life-cycle
You can have a look at this basic tutorial for differences between different contexts
Refer documentation
This is the expected behaviour. There is no way for Spring to know when you have finished using a prototype scope bean, so bean destruction is not managed by Spring for prototype scoped beans. From the documentation:
Although initialization lifecycle callback methods are called on all
objects regardless of scope, in the case of prototypes, configured
destruction lifecycle callbacks are not called.
See the Spring documentation for more information.
With regards to ApplicationContexts, you can choose the one that is best-suited to your application. It depends whether you want to use XML or annotation bean configuration, and whether or not you are running in a servlet container, for example. ApplicationContext itself is the interface at the root of the type heirarchy.
A singleton bean means that there is exactly one instance of that bean in the application context. That means if you do something like this:
HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
obj.setMessage("My message");
System.out.printIn(obj.getMessage());
HelloSpring anotherObj = (HelloSpring) context.getBean("helloSpring");
System.out.printIn(anotherObj.getMessage());
You will see "My message" in the console output twice.
For prototype beans everytime you try to get one of those from the application context you will get a new instance so if you run the above code again the second console output will be "null".
As there is no need for the container to call a destroy method for a prototype bean, it does not and the behavior is correct.
The difference between the said classes are that they are an interface, an abstract class and a concrete class respectively, to understand better about that concepts I suggest reading the official oracle documentation for java in here Oracle Java Tutorials.
your application could ask for new instances of prototype beans every 10 milliseconds, do something with the bean, and then let it go out of scope. If Spring had to destroy() them when the application shuts down, it would have to keep a reference to every created prototype bean, preventing them to be garbage-collected, and thus causing a memory leak.
I also tried to get a destroy event of bean which's scope is "prototype".
So I read all answers above and try by their answers.
At result, I reach out that there is no way to detect a destroy even of prototype bean.
Although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called.
see here (https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype)
Please check your scope type in your spring configuration file.
If scope="prototype" then change it to scope="singleton"
<bean id="helloWorld" class="com.example.test.HelloWorld"
init-method="init" destroy-method="destroy">
<property name="message" value="Hello World!" />

Spring configured mock giving two different instances

Note: I have purposefully removed words from the names of classes and objects, so please excuse the horribly names in my code examples
I've got a test class that sets up my application using some test Spring context files. The application is a wrapper to a web service.
As this is a test, I have mocked the main interface to the web service in question (the ITransporter class). This gives me the ability to set expectations so that I can check that the requests sent to the web service are: in the expected format; have the expected fields complete; etc...
My mock is defined in a file called test-beans-context.xml and is passed into some service beans, as follows:
<bean id="mockTransporter" class="org.easymock.EasyMock" factory-method="createMock" scope="singleton">
<constructor-arg index="0" value="transport.ITransporter" />
</bean>
<bean id="accountService" class="service.AccountService">
<property name="transporter" ref="mockTransporter" />
</bean>
This context file is used in 2 places. (And I fear this is where my problem arises.)
The first being the test class, which is defined as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration( locations={"classpath:test-beans-context.xml"} )
public class AbstractIntegrationTest {
#Autowired
private ITransporter mockTransporter;
//Some tests that perform expectations like the following:
// EasyMock.reset( this.mockTransporter );
// EasyMock.expect( this.mockTransporter.sendRequest( EasyMock.capture(this.requestXmlCapture) ) ).andReturn( responseXml );
}
The second place is in a class that is within the logical trail for getting to sending the request. It loads a separate XML context file /lite-api-context.xml that then imports the test one in my test set up.
public class Factory implements IFactory {
public Factory() {
context = new ClassPathXmlApplicationContext("/lite-api-context.xml");
}
#Override
public IAccountService getAccountService() {
return (IAccountService) context.getBean("accountService");
}
}
And lite-api-context.xml includes this:
<import resource="classpath:/test-beans-context.xml" />
My problem is that in the test class, I'm getting a different instance of the mocked ITransporter to the one that is ultimately being used by my other services. So the expectations I set up are never actually executed as the mocks end up being different instances.
Is there a way to ensure I get the same instance in both places?
Or am I going to have to create my own singleton test implementation of the ITransporter interface? (Basically creating a stub that behaves exactly like my mock does now.)
EDIT: (Answer)
As The Thom said, it appears I need to create my own class to manage the mock.
I wanted to add my solution here too in case anyone stumbled across a similar problem.
Just wrote a quick static class like this:
public class MockTransporter {
private static ITransporter mockTransporter = EasyMock.createMock(ITransporter.class);
public static final ITransporter getInstance() {
return mockTransporter;
}
}
And had to change the XML config to this:
<bean id="mockTransporter" class="MockTransporter" factory-method="getInstance" />
Oh yeah, that's a problem. When you create a new context that's like creating a new object space for Spring. The one created in your XML file is different from the one created in your handmade context. They will always produce different variables.
I've been burned on that one before.
You're only hope if you want the same ones is to manage your own singletons.
The ideal way to solve this problem would be to create the Factory as a Spring bean as well, and inject the AccountService into the Factory bean.
In general context.getBean() should be avoided in production code because it harms the concept of Inversion of Control (for more information see: Why is Spring's ApplicationContext.getBean considered bad?). It's okay to use it in test code though.

How to avoid using ApplicationContext.getBean() when implementing Spring IOC

I'm just getting started with Spring IOC concept. I often see most of the examples found in the internet use the code to get the object.
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) appContext.getBean("hello");
As a reference from these questions 1 and 2 in the stackoverflow. I've inferred that, it's not necessary to use appContext.getBean("hello") in the code which is considered to be the bad practice. Also, not recommended anymore. Correct me right here, If my inference is wrong.
Keeping that in view, I have made changes in my project accordingly.
Here's my 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-3.2.xsd">
<bean id="utilClassRef" class="org.hd.derbyops.DUtils" lazy-init="false" />
<bean id="appContext" class="org.hd.derbyops.ContextProvider" lazy-init="false">
<property name="utils" ref="utilClassRef" />
</bean>
</beans>
My contextProvider Class Code
public class ContextProvider implements ApplicationContextAware {
private static ApplicationContext ctx;
/**
* Objects as properties
*/
private static DUtils utils;
public void setApplicationContext(ApplicationContext appContext)
throws BeansException {
ctx = appContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
public static DUtils getUtils() {
return utils;
}
public void setUtils(DUtils dUtilsRef) {
utils = dUtilsRef;
}
}
For instance, consider a class A that depends on org.hd.derbyops.DUtils.
I'm using the following code line
ContextProvider.getUtils();
inorder to get DUtils Object in class A, thus avoiding usage of ApplicationContext.getBean() anywhere in my code.
Assume, if I have 10 classes and my class A is dependent on all of them, whose objects to be created and accessed without using ApplicationContext.getBean(). In that case also, as done above, I have a thought of creating properties of ContextProvider class followed by setter's and getter's of that property, where in get<PropertyName> is static. So that, I can use it wherever I'm in need of an object, like this
ContextProvider.get<PropertyName>;
Here's my brief question.
Firstly, Is my approach right? If it's right, loading all the beans at the start-up, wouldn't it be a performance killer? How would you do that in your applications without calling getBean atleast more than once?
If you were to design a web-application & you were to implement Spring IOC, without using ApplicationContext.getBean() in any of the code. How would you do that?
Note: with reference to the other questions tagged above
Calling ApplicationContext.getBean() is not Inversion of Control!
The simple answers are yes and no, no, and no. And finally, do a search online for spring MVC, as this probably does what you want.
So, your approach. Yes, you've got most of it right. However, it's considered very bad practice to use static methods for everything. And, you don't need to. Spring is based on the idea that you can simply create normal pojos, and spring will use them as singletons, and inject them into one another (it can also create objects on the fly, but I'm going for the common case here). If you use static classes and methods then:
You can't mock them for unit testing (you're using JUnit right?)
You can't use them with inheritance
Static initialisers are a great way to loose exceptions
etc, etc
So, yes to injection, and no to static stuff.
Next, performance. You're right in that it's a lot slower to use spring, but, if you do all your injection on startup it only happens once. Spring is meant for server side applications where there is likely to be a number of singleton classes passing data around. So, there might be a class to get stuff from a DB, one to process it, and one to display it, and spring is used to wire them together.
If you're using spring in an application where you start up repeatedly, like a command line app, then you are using it for the wrong sort of application, and you probably want to use a builder or something. Spring is meant for big enterprise apps that aren't restarted often.
Finally, if you simply inject all the dependencies for a class into it at startup, and you do this with all your classes, then you don't need to do any getBean stuff at all. Also, using the init-method and destroy-method attributes on a bean means that you can start up processes once spring has finished injecting dependencies. You need only load the context, and your app will spring (pun intended) into existence.
As for web projects, Spring MVC basically takes the whole inversion of control pattern and applies it to web applications. The spring stuff gets loaded by the container, and you can define the URLs to respond to using nothing more than bean names. And most of your code can stay as pojos. If you have something insanely complex, you may want to look at spring web flow, but I'd advise you to make sure that your spring foo is very strong before attempting that.
Here's my example for getting the first instance without actually calling getBean() on ApplicationContext.
public class Test{
// Declare private static variable so that we can access it in main()
private static Triangle triangle;
// Use constructor injection to set the triangle
public Test(Triangle triangle) {
Test.triangle = triangle;
}
public static void main(String[] args) {
// Specify the context file containing the bean definitions
// Spring automatically creates instances of all the beans defined
// in this XML file. This process is performed before you actually make
// a getBean("beanName") call.
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// Use instance methods of triangle
Test.triangle.draw();
}
}
You can use another way:
In spring.xml (Your bean configuration XML file)
<bean class="com.example.Test" init-method="myMethod">
<constructor-args ref="triangle"/>
</bean>
Now for your main class
public class Test {
private final Triangle triangle;
public Test (Triangle triangle) {
this.triangle = triangle;
}
public static void main (String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
}
// Called by Spring immediately after the Triangle Bean has been created and
// all the properties for the bean have been set. This method name must match
// the one specified with destroy-method attribute in spring.xml
public void myMethod () {
triangle.draw();
}
}

Spring injecting a static (global) singleton

I have a class that looks like so:
public class Configurator {
private static Configurator INSTANCE = null;
private int maxRange = 1;
// many other properties; each property has a default value
private static synchronized Configurator getInstance() {
if(INSTANCE == null)
return new Configurator();
return INSTANCE;
}
public static int getMaxRange() {
getInstance().maxRange;
}
public static void setMaxRange(int range) {
getInstance().maxRange = range;
}
// Getters and setters for all properties follow this pattern
}
It serves as a global configuration object that can be set on app startup, and then is used by dozens of classes throughout the project:
// Called at app startup to configure everything
public class AppRunner {
Configurator.setMaxRange(30);
}
// Example of Configurator being used by another class
public class WidgetFactory {
public void doSomething() {
if(Configurator.getMaxRange() < 50)
// do A
else
// do B
}
}
I'm now importing this code into a Spring project, and am trying to configure my Sprinig XML (beans). My guess is that I could define a lone Configurator bean like so (or something similar):
<bean id="configurator" class="com.me.myapp.Configurator" scope="singleton">
<property name="maxRange" value="30"/>
<!-- etc., for all properties -->
</bean>
That way, when WidgetFactory#doSomething executes, Spring will have already loaded the Configurator class and configured it ahead of time.
Is it correct for me to set the scope="singleton", or does this not matter? Am I setting the static properties correctly? Is there anything else I need to do or consider here? Thanks in advance.
There are some difference between Singleton as a design pattern and Spring's singleton facility. Singleton as a design pattern will ensure you have one object of class defined per Class Loader. Spring's singleton facility (and approach), in contrast, will define one instance per Spring Context.
In this case you can utilize your getInstance() method to be used by Spring to grab your object instance:
<bean id="configurator" class="com.me.myapp.Configurator" factory-method="getInstance">
</bean>
With Spring the singleton bean scope is the default therefore you don't need to define it.
If you want to use configurator as a Spring bean you will have to inject it in other objects, not use getInstance() to grab it. So in other Spring beans use #Autowired or define reference to bean through xml file. If you don't reorganize usage of configurator in other classes, there will no be difference, Spring will instantiate your class, but you will use it as before.
Also I saw that you have an error in designing your singleton. Your getInstance() method should be public, and other methods should not be static. In the example you've used you should use Singleton like this:
Configurator.getInstance().someMethod()
In this case you actually just use the Singleton class, without instantiating any objects! See wikipedia on Singleton (with Java example) for more information on the Singleton design pattern and how to use it.
NOTE: It's worth knowing and attempting to use Configurator as a Singleton and make use Spring's singleton facility. If you do this the benefits will be that you can
Remove the getInstance() method
Make your constructor public
Let the Spring instantiate that single object.
Beans are singleton by default. You can find this/more information out via the spring website.
You shouldn't instantiate a new Configurator in getInstance because it won't refer to the spring loaded bean and that could cause some serious issues. You can wire this bean in and then leave it alone, it won't be null because you've wired it in (and if it is your program will have failed initialising).
Yes, if you want something global, singleton scope is the right option.
a few things worth mentioning here are :
The default scope in spring is singleton, so you don't need to
explicitly set your bean as singleton scope.
Using Spring you do not need to write Singleton pattern style code, such as private instances and a factory methods. That is because Spring will
guarantee that there is only one single instance per Spring
container. Not even to say, your factory method is private.
By the way: this is not Thread-safe:
if(INSTANCE == null)
return new Configurator();
return INSTANCE;
}
Whereas this would be:
private static Configurator INSTANCE = new Configurator();
(Eager Initialization)
private static volatile Singleton _instance = null;
(Lazy initialization with volatile keyword)
It has to do with the way Java allocates Memory and creates instances. This is not atomic, but done in two steps and can be interfered by the thread scheduler.
See also http://regrecall.blogspot.de/2012/05/java-singleton-pattern-thread-safe.html.

Spring: Using "Lookup method injection" for my ThreadFactory looks not scalable

We're building a ThreadFactory so everytime a singleton controller needs a new thread, i get a new instance everytime.
Looking at Lookup method injection looks good but what if we have multiple thread classes? I like the fact that i can autowire my threadBeans.
like:
public abstract class ThreadManager {
public abstract Thread createThreadA();
public abstract Thread createThreadB();
}
and config:
<bean id="threadManager" class="bla.ThreadManager" singleton="true">
<lookup-method name="createThreadA" bean="threadA" />
<lookup-method name="createThreadB" bean="threadB"/>
</bean>
<!-- Yes! i can autowire now :)-->
<bean id="threadA" class="bla.ThreadA" singleton="false" autowire="byType">
<bean id="threadB" class="bla.ThreadB" singleton="false" autowire="byType">
and usage:
threadManager.createThreadA();
Question: I don't want to create an abstract "create" method for every new threadclass.
Is it possible to make this generich like:
threadManager.createThread(ThreadA.class);
I also looked at ServiceLocatorFactoryBean but for multiple classes i have to pass the bean name (not type safe).
Thank you
I don't think there is a way to do that automatically. And if you don't want to use ExecutorService, as suggested, you you can achieve this manually, if it is such a problem for you (but I don't think it is)
make your threadManager implement ApplicationContextAware or BeanFactoryAware, thus obtaining the application context / bean factory
in your createThread(..) method use the context/factory obtained above to get an instance of the thread bean (which should be of scope prototype of course)

Categories

Resources