• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • Devaka Cooray
Saloon Keepers:
  • Ganesh Patekar
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • salvin francis
Bartenders:
  • Ron McLeod
  • Frits Walraven
  • Pete Letkeman

two instances are created  RSS feed

 
Ranch Hand
Posts: 1703
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, in Spring documentation, there is an example:


Is ClientDao bean created twice?
But it is a singleton bean though.

The explanation is not clear to me:


clientDao() has been called once in clientService1() and once in clientService2(). Since this method creates a new instance of ClientDaoImpl and returns it, you would normally expect having 2 instances (one for each service). That definitely would be problematic: in Spring, instantiated beans have a singleton scope by default. This is where the magic comes in: All @Configuration classes are subclassed at startup-time with CGLIB. In the subclass, the child method checks the container first for any cached (scoped) beans before it calls the parent method and creates a new instance. Note that as of Spring 3.2, it is no longer necessary to add CGLIB to your classpath because CGLIB classes have been repackaged under org.springframework.cglib and included directly within the spring-core JAR.


 
Bartender
Posts: 19807
93
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Spring Beans are produced by a factory. So you never invoke "new" to create a Spring Bean. Any "new" operations you do are outside the scope of Spring unless you manually add them to the Spring bean inventory (which isn't something commonly done). So beans that are instantiated from a Spring configuration or by Spring injection are - unless defined otherwise - singletons. But there's nothing in Java or Spring that can detect non-singleton instances of beans created manually via "new" (or newInstance). The only way to enforce singleton instances in such cases is to  code the beans themselves to only instantiate once.

Just to clarify. If you ask a Spring factory for a bean, it will first check to see if the bean is defined as a singleton (the default). If so, it will check its collection to see if the bean already exists. If it does not exist, then the factory will construct the bean, note it in its bean inventory, and return the bean to the factory method caller. If the bean is a singleton and is already in inventory, then the factory method returns a reference to that existing bean. And again, this only works if you ask for the bean through the Spring factory. Manually instantiating the bean via "new" or "newInstance" has no way to consult with the Spring bean factory. Or, for that matter, catalog the newly-created bean in Spring's inventory.
 
Himai Minh
Ranch Hand
Posts: 1703
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Tim. Thanks for the reply about bean factory.
In the above example from the Spring documentation, there are codes like this:

The clientService  object is not instantiated by Spring injection, but it is created by new operator. So, clientService is outside the scope of Spring. But the method is annoatation with @Bean.
So, is clientService considered as a Spring bean?
 
Tim Holloway
Bartender
Posts: 19807
93
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, the ClientService is not a Spring bean the way you did it. And actually, the recommended way to create it would be to define the ClientService as a Spring bean and have Spring inject/Autowire the ClientServiceImpl into the ClientService class to be returned by the clientService1 method.

Or actually, since you've basically just created a mini-factory, ClientService should more properly be defined as a Java Interface that ClientServiceImpl implements and you'd configure Spring to manufacture and return a ClientServiceImpl to whatever downstream beans requested a ClientService.

The actual instantiation of ClientServiceImpl in either case would either be by annotating the ClientServiceImpl.java file as a Spring bean, or if this is not possible or desirable, to define it in your Spring configuration (applicationContext.xml or whatever).
 
Himai Minh
Ranch Hand
Posts: 1703
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Tim,
You mean the object returned from @Bean method is not a bean?
But in the specification it says:


   2.2. @Bean
@Bean is a method-level annotation and a direct analog of the XML <bean/> element. The annotation supports most of the attributes offered by <bean/>, such as: init-method, destroy-method, autowiring, lazy-init, dependency-check, depends-on and scope.
2.2.1. Declaring a bean
To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory. By default, the bean name will be the same as the method name (see bean naming for details on how to customize this behavior). The following is a simple example of a @Bean method declaration:
@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}


Obviously, @Bean = <bean> in the configuration XML.
 
Tim Holloway
Bartender
Posts: 19807
93
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK. Sorry. I mis-read some stuff.

The stuff you are describing is a way to define Spring configuration in logic, rather than via direct annotations or a config file. The @Bean methods are factory helpers. And while you have defined 2 different methods which construct  ClientServiceImpl objects, these are distinct objects, even though they both belong to the same class. The Spring factory retrieves beans by name. So these are "singleton" in the sense that there should only be one instance of clientService1 (that is, a ClientServiceImpl named "clientService1") and one instance of clientService2, they are not literally Singletons, in that the same class is instantiated twice. And, again, only if you're going by default rules. If you wanted to you could, for example, define a single instance of clientService1, but have Spring generate multiple instances of clientService2, just by setting the Spring configuration options accordingly.

The @Bean thing confused me, since I've never had need of a logic-based configuration and I was thinking it was a CDI re-refinition of one of the more common Spring annotations.

In fact, for DAO's, I use the @Repository annotation directly on the DAO class definition. Along witjh @Transactional.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!