Spring Prototype-Bean Provider without #Autowired - java

I have a prototype Bean which is instantiated by singleton bean with a Provider:
#Component
#Scope("prototype")
class MyPrototype {}
#Component
class MySingleton {
#Autowired
javax.inject.Provider<MyPrototype> prototypeFactory;
}
This works fine, but our company rules state that #Autowired is not allowed; the common pattern is #Resource(SingletonBeanClass.BEAN_ID).
Is it possible to annotate the Provider this way so the Spring lookup can create it?
I'm aware I can add a factory method with #Lookup, or a singleton factory bean, but I prefer the Provider.
EDIT:
I didn't get it to work this way and in the end had to edit spring.xml; see below for details.

As you have an XML configuration file, you can configure it via XML in the following way:
<bean id="myPrototype" class="some.package.MyPrototype" scope="prototype" />
<bean id="mySingleton" class="some.package.MySingleton">
<lookup-method name="getPrototypeFactory" bean="myPrototype "/>
</bean>
In this way, you have to access to the myPrototype with the getPrototypeFactory() and not directly to the property. You can even remove the annotations on those 2 classes.
For any extra details, you can look at the following blog post Injecting a prototype bean into a singleton bean

For reference, if someone comes across this via Google:
I ended up needing to declare it in the spring.xml. I tried #Lookup, but even that didn't work due to the prototype-bean referencing yet another prototype-bean.
This is how it was recommended here,
but it does not work:
#Component("proto1")
#Scope("prototype")
class MyPrototypeBean1 {
#Lookup(value="proto2")
protected MyPrototypeBean2 createBean2() { return null; }
}
#Component("proto2")
#Scope("prototype")
class MyPrototypeBean2 {
}
#Component("singleton")
class MySingleton {
#Lookup(value="proto1")
protected MyPrototypeBean1 createBean1() { return null; }
}
This results in the error message "Cannot apply #Lookup to beans without corresponding bean definition" when trying to create "innerBean...".
I assume it is due to "lookup methods cannot get replaced on beans returned from factory methods where we can't dynamically provide a subclass for them" as is quoted in the link above.
So what I ended up doing in the spring.xml:
<bean name="proto2" class="my.package.PrototypeBean2" />
<bean name="proto1" class="my.package.PrototypeBean1" >
<lookup-method name="createBean2" bean="proto2" />
</bean>
<bean name="singleton" class="my.package.SingletonBean" >
<lookup-method name="createBean1" bean="proto1" />
</bean>
And this works.
For the unit tests, I had to subclass the respective classes:
class SingletonUnitTest {
#Mock
MyPrototypeBean1 bean1;
#InjectMocks
DummySingleton sut;
#Before public void setBean1() {
sut.bean = bean1;
}
static class DummySingletonBean extends MySingeton {
MyPrototypeBean1 bean;
protected MyPrototypeBean1 createBean1() {
return bean;
}
}
}

Related

Spring Bean Injection Failing Due To Proxy

Spring Version: 3.2.4.RELEASE and 3.2.9.RELEASE
Mockito Version: 1.8.5
I've been trying to introduce H2 tests to an old project for integration testing, and I've been running into a few issues. Due to the way transactions were propagating, I needed to mock out an autowired class. I've done this before, but I'm now running into severe problems. The following error message is being thrown when initialising the test:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.stuff.XMLITCase': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'TheProcessor' must be of type [com.stuff.XMLBatchFileProcessor], but was actually of type [$Proxy118]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:307)
Diving into this a bit deeper, it turns out the the bean is in-fact a proxy. If we check the AbstractBeanFactory (round line 239), we can see the proxy:
sharedInstance = {$Proxy117#7035} "com.stuff.XMLBatchFileProcessor#66c540d0"
h = {org.springframework.aop.framework.JdkDynamicAopProxy#7039}
The only problem is, I've no clue where this is coming from. I've gone over the config and dependencies, and can't find anywhere that this should be happening.
Project Setup
Unfortunately I can't give a sample project for this, but I'll go over my test configuration. I have a root class that I extend for the tests:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:/spring/spring-test-context.xml"})
#TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public abstract class AbstractIntegrationTest {
}
This simply loads in some spring config and rolls back the transactions after each test.
The spring config is nothing strange either, though there is one difference between my other module and this one. This is the transaction manager and session factory:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
...
</bean>
In my other module, I'm using an entityManagerFactory, and a different transaction manager:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>
The actually class has some autowired fields, and the usual #Service annotation:
#Service(value = "TheProcessor")
public final class XMLBatchFileProcessor extends BatchFileProcessor implements IXMLBatchProcessor {
Finally, the actual test is as follows:
public class XMLITCase extends AbstractIntegrationTest {
#Resource(name = "TheProcessor")
#InjectMocks
private XMLBatchFileProcessor xmlProcessor;
#Mock
private ProcessHelper processHelper;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() throws Exception {
Assert.assertNotNull(xmlProcessor);
}
}
If I replace the XMLBatchFileProcessor with the interface and autowire the field, then there aren't any problems compiling. Mockito, however, never replaces the autowired bean with the mocked object. If it did, then I wouldn't bother with the #Resource annotations and naming the service, thus avoiding the Proxy issue.
Any assistance on this would be appreciate. I'll be focusing on the session factory and the differences there, but it's quite possible that I'm missing something else entirely.
EDIT
Going on Sotirios' comment, I had another look this morning and indeed had missed that the xmlProcessor has a #Transactional annotation, thus meaning that the class needs to be proxied. If I remove the final declaration and let CGLib enhance it, then Mockito does replace the bean when initMocks(this) this called. When a method is called, however, CGLib seems to replace all the beans with Spring enhanced versions, hence overwriting the Mockito version.
What is the correct way to use both Mockito and Spring in an integration test for a class with #Transactional annotations?
Alright, once I realised that the class was being proxied due to the #Transactional annotation, the solution to the problem became clearer. What I needed to do was unwrap the proxy, and set the mocked object directly on that:
So in my AbstractIntegrationTest:
/**
* Checks if the given object is a proxy, and unwraps it if it is.
*
* #param bean The object to check
* #return The unwrapped object that was proxied, else the object
* #throws Exception
*/
public final Object unwrapProxy(Object bean) throws Exception {
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
bean = advised.getTargetSource().getTarget();
}
return bean;
}
Then in my #Before:
#Mock
private ProcessHelper processHelper;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
IXMLBatchProcessor iXMLBatchProcessor = (IXMLBatchProcessor) unwrapProxy(xmlProcessor);
ReflectionTestUtils.setField(iXMLBatchProcessor , "processHelper", processHelper);
}
This left all the #Autowired classes intact, while injecting the correct mocked object.
you can optimise the accepted response using the class AopTestUtils that provides the methods:
getTargetObject to unwrap the top-level proxy if exists
getUltimateTargetObject to unwrap all levels of proxies if they
exist

how to inject parent class property with spring annotation

parent class is like this:
public class BaseDAO{
private DBRoute defaultDB;
public DBRoute getDefaultDB()
{
return this.defaultDB;
}
public void setDefaultDB(DBRoute defaultDB)
{
this.defaultDB = defaultDB;
}
}
I have create beans like below:
<bean id="adsConfigDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsConfig" />
</bean>
<bean id="adsBizDateDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsBizDate" />
</bean>
I want to inject superclass property defaultDB in subclass through byName, not byType, which is in subclass inject defaultDB using adsConfigDB or adsBizDateDB. Is there any way to do this with spring annotations? I already tried Autowired or Resource with constructor which doesn't work. By the way, I already know this can be done using XML.
#Qualifier annotation – This annotation is used to avoid conflicts in bean mapping and we need to provide the bean name that will be used for autowiring. This way we can avoid issues where multiple beans are defined for same type. This annotation usually works with the #Autowired annotation. For constructors with multiple arguments, we can use this annotation with the argument names in the method.
Your code will be like this..
#Autowired
#Qualifier("adsConfig")
private DBRoute defaultDB;

Spring not injecting bean if it is instantiated on definition

I have a session scoped bean defined like so:
<!-- this is where the serviceImpl bean is defined -->
<import resource="classpath:META-INF/*-core-context.xml"/>
<bean id="myBean" class="com.company.Bean">
<property name="service" ref="serviceImpl"/>
</bean>
Now inside the bean I have defined a default value for the injected service like so:
public class Bean {
private Service service = new NullService();
public void setService(Service service) {
this.service = service;
}
}
What I want to do is to provide the ability to optionally inject the service and if you choose not to the Bean will use the NullService implementation which simply does nothing, not affecting the bean logic in any way.
The problem is that for some reason the serviceImpl is never injected and I always end up with the NullService implementation.
So is there some spring setting or feature which prevents it from injecting it ? Or do you have any other ideas on why this might happen ?
More info
This is the setter that spring uses to inject the service:
public void setPermissionsService(PermissionService permissionsService) {
this.permissionsService = permissionsService;
System.out.println("setting permissions service to: " + permissionsService.getClass().getName());
if (this.permissionsService instanceof NoopPermissionsServiceImpl) {
System.out.println("NULL IMPLEMENTATION");
}
else if (this.permissionsService instanceof PermissionServiceImpl) {
System.out.println("CORRECT IMPLEMENTATION");
}
else {
System.out.println("WHAT ?!?!");
}
}
It prints "WHAT ?!?!".
So it turns out spring sets it to a dynamic proxy $Proxy859. Is there a way to see the class the proxy is proxying ?
You seem to be lacking a definition for your serviceImpl bean in your configuration. Something like
<bean id="serviceImpl" class="com.company.ServiceImpl" />
The only solution I see to your problem is to reverse-engineer this a bit. Do something like that in the same spring.xml:
<bean id="myBean" class="com.company.Bean">
<property name="service" ref="testServiceImpl"/>
</bean>
<bean id="testServiceImpl" class="com.company.TestServiceImpl" />
Then implement the TestServiceImpl with simple debug messages indicating that construction and your service call is actually working. This has to work. If it does you have a problem with your original service definition. If not you have a problem in your Bean.
Try to narrow the problem to a simpler. And then work into the simpler problem.
Good luck!
Instead of using instanceof use Class.isAssignableFrom(Class)

request scoped beans in spring testing

I would like to make use of request scoped beans in my app. I use JUnit4 for testing. If I try to create one in a test like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring/TestScopedBeans-context.xml" })
public class TestScopedBeans {
protected final static Logger logger = Logger
.getLogger(TestScopedBeans.class);
#Resource
private Object tObj;
#Test
public void testBean() {
logger.debug(tObj);
}
#Test
public void testBean2() {
logger.debug(tObj);
}
With the following bean definition:
<?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 class="java.lang.Object" id="tObj" scope="request" />
</beans>
And I get:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gov.nasa.arc.cx.sor.query.TestScopedBeans': Injection of resource fields failed; nested exception is java.lang.IllegalStateException: No Scope registered for scope 'request'
<...SNIP...>
Caused by: java.lang.IllegalStateException: No Scope registered for scope 'request'
So I found this blog that seemed helpful:
http://www.javathinking.com/2009/06/no-scope-registered-for-scope-request_5.html
But I noticed he uses AbstractDependencyInjectionSpringContextTests which seems to be deprecated in Spring 3.0.
I use Spring 2.5 at this time, but thought it shouldn't be too hard to switch this method to use AbstractJUnit4SpringContextTests
as the docs suggest (ok the docs link to the 3.8 version but I'm using 4.4). So I change the
test to extend AbstractJUnit4SpringContextTests... same message. Same problem. And now the prepareTestInstance() method I want
to override is not defined. OK, maybe I'll put those registerScope calls somewhere else... So I read more about TestExecutionListeners and think that would be better since I don't want to have to inherit the spring package structure. So
I changed my Test to:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring/TestScopedBeans-context.xml" })
#TestExecutionListeners({})
public class TestScopedBeans {
expecting I would have to create a custom listener but I when I ran it. It works! Great, but why? I don't see where any of the stock listeners
are registering request scope or session scope, and why would they? there's nothing to say I want that yet, this might not be a Test for Spring MVC code...
Solution for Spring 3.2 or newer
Spring starting with version 3.2 provides support for session/request scoped beans for integration testing.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class)
#WebAppConfiguration
public class SampleTest {
#Autowired WebApplicationContext wac;
#Autowired MockHttpServletRequest request;
#Autowired MockHttpSession session;
#Autowired MySessionBean mySessionBean;
#Autowired MyRequestBean myRequestBean;
#Test
public void requestScope() throws Exception {
assertThat(myRequestBean)
.isSameAs(request.getAttribute("myRequestBean"));
assertThat(myRequestBean)
.isSameAs(wac.getBean("myRequestBean", MyRequestBean.class));
}
#Test
public void sessionScope() throws Exception {
assertThat(mySessionBean)
.isSameAs(session.getAttribute("mySessionBean"));
assertThat(mySessionBean)
.isSameAs(wac.getBean("mySessionBean", MySessionBean.class));
}
}
Read more: Request and Session Scoped Beans
Solution for Spring before 3.2 with listener
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class)
#TestExecutionListeners({WebContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class})
public class SampleTest {
...
}
WebContextTestExecutionListener.java
public class WebContextTestExecutionListener extends AbstractTestExecutionListener {
#Override
public void prepareTestInstance(TestContext testContext) {
if (testContext.getApplicationContext() instanceof GenericApplicationContext) {
GenericApplicationContext context = (GenericApplicationContext) testContext.getApplicationContext();
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST,
new SimpleThreadScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION,
new SimpleThreadScope());
}
}
}
Solution for Spring before 3.2 with custom scopes
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class, locations = "test-config.xml")
public class SampleTest {
...
}
TestConfig.java
#Configuration
#ComponentScan(...)
public class TestConfig {
#Bean
public CustomScopeConfigurer customScopeConfigurer(){
CustomScopeConfigurer scopeConfigurer = new CustomScopeConfigurer();
HashMap<String, Object> scopes = new HashMap<String, Object>();
scopes.put(WebApplicationContext.SCOPE_REQUEST,
new SimpleThreadScope());
scopes.put(WebApplicationContext.SCOPE_SESSION,
new SimpleThreadScope());
scopeConfigurer.setScopes(scopes);
return scopeConfigurer
}
or with xml configuration
test-config.xml
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="request">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
Source code
Source code for all presented solutions:
https://github.com/mariuszs/spring-test-web
I've tried several solutions, including #Marius's solution with the "WebContextTestExecutionListener", but it didn't work for me, as this code loaded the application context before creating the request scope.
The answer that helped me in the end is not a new one, but it's good:
http://tarunsapra.wordpress.com/2011/06/28/junit-spring-session-and-request-scope-beans/
I simply added the following snippet to my (test) application context:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="request">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
Good luck!
A solution, tested with Spring 4, for when you require request-scoped beans but aren't making any requests via MockMVC, etc.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(/* ... */)
public class Tests {
#Autowired
private GenericApplicationContext context;
#Before
public void defineRequestScope() {
context.getBeanFactory().registerScope(
WebApplicationContext.SCOPE_REQUEST, new RequestScope());
RequestContextHolder.setRequestAttributes(
new ServletRequestAttributes(new MockHttpServletRequest()));
}
// ...
The test passes because it isn't doing anything :)
When you omit the #TestExecutionListeners annotation, Spring registers 3 default listeners, including one called DependencyInjectionTestExecutionListener. This is the listener responsible for scanning your test class looking for things to inject, including #Resource annotations. This listener tried to inject tObj, and fails, because of the undefined scope.
When you declare #TestExecutionListeners({}), you suppress the registration of the DependencyInjectionTestExecutionListener, and so the test never gets tObj injected at all, and because your test is not checking for the existence of tObj, it passes.
Modify your test so that it does this, and it will fail:
#Test
public void testBean() {
assertNotNull("tObj is null", tObj);
}
So with your empty #TestExecutionListeners, the test passes because nothing happens.
Now, on to your original problem. If you want to try registering the request scope with your test context, then have a look at the source code for WebApplicationContextUtils.registerWebApplicationScopes(), you'll find the line:
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
You could try that, and see how you go, but there might be odd side-effects, because you're not really meant to do this in a test.
Instead, I would recommend rephrasing your test so that you don't need request scoped beans. This shouldn't be difficult, the lifecycle of the #Test shouldn't be any longer than the lifecycle of a request-scoped bean, if you write self-contained tests. Remember, there's no need to test the scoping mechanism, it's part of Spring and you can assume it works.
This is still an open issue:
https://jira.springsource.org/browse/SPR-4588
I was able to get this to work (mostly) by defining a custom context loader as outlined in
http://forum.springsource.org/showthread.php?p=286280
Test Request-Scoped Beans with Spring explains very well how to register and create a custom scope with Spring.
In a nutshell, as Ido Cohn explained, it's enough to add the following to the text context configuration:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="request">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
Instead of using the predefined SimpleThreadScope, based on ThreadLocal, it's also easy to implement a Custom one, as explained in the article.
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
public class CustomScope implements Scope {
private final Map<String , Object> beanMap = new HashMap<String , Object>();
public Object get(String name, ObjectFactory<?> factory) {
Object bean = beanMap.get(name);
if (null == bean) {
bean = factory.getObject();
beanMap.put(name, bean);
}
return bean;
}
public String getConversationId() {
// not needed
return null;
}
public void registerDestructionCallback(String arg0, Runnable arg1) {
// not needed
}
public Object remove(String obj) {
return beanMap.remove(obj);
}
public Object resolveContextualObject(String arg0) {
// not needed
return null;
}
}
MariuszS' solution works, except I couldn't get the transaction committed properly.
It seems the newly released 3.2 has finally made testing request/session scoped beans first class citizens. Here's a couple of blogs for more details.
Rossen Stoyanchev's Spring Framework 3.2 RC1: Spring MVC Test Framework
Sam Brannen's Spring Framework 3.2 RC1: New Testing Features
NOT reading the docs sometimes drives one crazy. Almost.
If you are using shorter-lived beans (request scope for example), you most likely also need to change your lazy init default! Otherwise the WebAppContext will fail to load and tell you something about missing request scope, which is of course missing, because the context is still loading!
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-lazy-init
The Spring guys should definitely put that hint into their exception message...
If you don't want to change the default, there is also the annotation way: put "#Lazy(true)" after #Component etc. to make singletons initialize lazy and avoid instantiating request-scoped beans too early.

Spring prototype beans in combination with singleton beans and dependency injection. Is there an approach that is configuration only?

I have a singleton bean which needs for each call of a function to return a reference to a different (new) prototype bean. The only way that I can think of doing this is to programmatically retrieve a new prototype bean instance from the BeanFactory/ApplicatioContext by invoking its getBean() method. Code sample will follow...
Is there a better way to do this? Only via configuration, hopefully? (Personally, I doubt there is...)
<bean id="protoBean" scope="prototype"
class="com.blahblah.ProtoBean" />
<bean id="singletonBean"
class="com.blahblah.SingletonBean" />
public class ProtoBean {
....
}
public class SingletonBean {
private BeanFactory factory;
public ProtoBean dispense() {
return (ProtoBean) factory.getBean("protoBean");
}
....
}
take a look at Method Injection
From Spring 3.0, we can use <aop:scoped-proxy> for dependency injection of the proper scope. Behind the scene, Spring injects proxied objects and is responsible for finding the right scope context, may it be prototype, session or request etc. See the official documentations here.
And to make life easier, Spring has also introduced proxyMode attribute for #Scope, so we are not limited to XML declarations only. For example:
#Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
Make sure to document clearly the injected bean is a proxy to warn others that getClass() and casting may not yield the expected result. Also, make sure equals() and hashCode() in the proxied class use access methods rather than directly accessing class variables.
Using method injection makes the singleton-bean class difficult to unit-test (you need to create a subclass to implement the method which gives out the dependency). Plus it's less reusable because you can't directly instantiate it, so if you're not using Spring and want to use this class, you'll need to subclass and provide the bean-returning method.
A better approach IMHO is to use a proxy, a prototype target source and a prototype target bean, as follows. Such a singleton-bean class is easily unit-testable and better reusable.
<bean id="targetPooledObject" class="pool.PooledObject" scope="prototype">
<constructor-arg value="42" />
</bean>
<bean id="prototypeTargetSource" class="org.springframework.aop.target.PrototypeTargetSource">
<property name="targetBeanName" value="targetPooledObject" />
</bean>
<bean id="pooledObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource" />
</bean>
<bean id="poolConsumer" class="pool.PoolConsumer">
<property name="pooledObject" ref="pooledObject" />
</bean>
Now we can inject pooledObject into a singleton bean (poolConsumer as shown above), and for every method call that we make on that singleton bean, (e.g. every time we call poolConsumer.callPooledObjectMethod() which in turn calls pooledObject.foo()) we get a new PooledObject bean.
Following is the corresponding code:
public class PooledObject
{
private int x;
public PooledObject(int x)
{
this.x = x;
}
public void foo()
{
System.out.println("foo called");
}
}
public class PoolConsumer
{
private PooledObject pooledObject;
public PooledObject getPooledObject()
{
return pooledObject;
}
public void setPooledObject(PooledObject pooledObject)
{
this.pooledObject = pooledObject;
}
public void callPooledObjectMethod()
{
pooledObject.foo();
}
}

Categories

Resources