Does spring allow us to do so? I was reading the documentation and found that:
Thus the initialization callback is called on the raw bean reference,
which means that AOP interceptors and so forth are not yet applied to
the bean.
So, I presume, spring creates aop proxy and inject it into a collaborating bean every time the dependency is needed. How can I avoid injecting such a proxy and provide a raw reference to a bean. In my particular case I'm injecting prototype-scoped beans into each other.
I think, avoiding injectink the proxy may improve the performance...
In essence, what is the difference between these two classes:
#ApplicationScoped
#Singleton
class A {}
#Dependent
#Singleton
class B {}
Contextual EJB instances
I prefer not to use #Inject when looking for EJB:s, unless the EJB is a #Stateful and I want the CDI container to manage the stateful's life-cycle which could be very convenient. Otherwise, using #Inject to retrieve a contextual EJB instance is a bit dangerous. For example, a #Remote client-view cannot be retrieved using CDI unless we also write a producer. Furthermore, class A and class B can not declare any other scope than what they currently do. CDI 1.1, section "3.2 Session beans" says:
A singleton bean must belong to either the #ApplicationScoped scope or
to the #Dependent pseudo-scope. If a session bean specifies an illegal
scope, the container automatically detects the problem and treats it
as a definition error.
Hence, apart from stateful beans, I see no point in using CDI when I go look for EJB:s.
A more mature version of the question
From the client code's perspective which uses #Inject to declare a dependency on either A or B, I cannot imagine there is a difference. In both cases, the call will be routed to a singleton EJB. Had I been the implementation author of a CDI provider, then I might even inject the real EJB proxy in both cases and ignore future calls asking for destruction of the dependent CDI proxy? The bottom line is that we may declare two different scopes on the EJB singleton class. So what's the difference?
I have the following scenario in my code base:
//this bean, which will be injected,
//is not annotated
public class HelperUtil {
//only default constructor with no args
public void doThis(String _in) {
//...
}
public void doThat() {
//...
}
}
In the below class we do the injection:
#Named
#Stateless
public class BusinessManager {
#PersistenceContext(unitName = "default")
private EntityManager em;
#Inject
private HelperUtil helperUtil ;
//...
}
Q1: When is the instance of HelperUtil which will be injected actually initialized by calling the default constructor? Is it done when the first client into which it is injected (like BusinessManager) is instantiated when the app server (in my case JBoss) starts (and that one will be initialized by the container because it is annotated as #Stateless)?
Q2: In the above exhibit, will HelperUtil remain a singleton as long as no client other than the container asks for an instance by calling the constructor directly and not obtaining an instance via DI?
Q3: What is the advantage of using DI and #Inject in this case vs. simply calling the constructor directly (HelperUtil helper = new HelperUtil();)?
It depends, but you can control these event to execute some code, for example:
If you need that your bean is executed when the app start you need to add #Startup annotation to your bean.
If you need to initialize your bean without access to other injected resources you can use the normal constructor.
If you need some method to be executed when the bean is initialized then use the #PostConstruct annotation in the method.
You need to remember that the creation depends on the scope of the bean, in you case, which is a stateless bean, the bean will be created if some client injects it and there are no other instance available, if is singleton then will bean created just once, in general the bean will be created when they are needed (a singleton bean initialize until the first client uses it, or at startup with the annotation)
EDIT:
For the third question, the advantage is that if you use a resource, or other bean inside your HelperUtil, they will be initialized with the proper values, for example, if you use an entity manager, or other beans inside your helper. If your helper will handle just things like static methods or other simple utilities then you are right, the advantage is none and you could simply manage like an static helper class, but if you need EE resources the you need the bean to be managed in order to get all injections and resources loaded
EDIT 2:
After some more years programming and using dependency injection in Java and C# Core, I can add: The question 3 is very open, using DI will allow your code to:
be less coupled, if you change your constructor, you then would have to go searching all the new ObjectModified(oldParams) to add the new parameters
more easy to test, because you can inject "fake objects" as dependencies, avoiding the need to load all the system and prepare the state for the test, for example, if you want to check some code that depends on the current hour, you could connect a fake provider in test mode to give always the same hour, or some sequence
Avoid cyclical dependency, where class A depends on B and B depends on A, normally this is more complex, like
ClasssA -> ClasssB -> ClasssC -> ClasssA
When this dependencies are present, you can start a modification, then modify the class that uses it, and so on... until somehow you find yourself modifying the same class as before!, so you start in a cycle because the communication path between your objects are complex.
When you use DI, this cycles can be detected early on, so you can rethink your architecture to avoid this productivity blackholes
DI is a very powerful tool to keep big projects maintainable, is now present in a lot of environments and frameworks because is very useful, if this still does not convince you, you can try start a project in Spring boot, PlayFramework, Net Core, Java EE, Ruby on Rails.... and many others that have include this as the normal flow and build a medium size app, then try without DI
Background: Everything within CDI operates within a Context. That being said
A managed bean's fields are instantiated, on request. From the spec:
When the container creates a new instance of a managed bean, session bean, or of any other Java EE component class supporting injection, the container must:
Initialize the values of all injected fields. The container sets the value of each injected field to an injectable reference.
What this means is that the first initialization of a dependent bean is when it's first called for, which is when the parent bean is initialized. Now, the JSF #ApplicationScoped has the eager="true" attribute, which allows beans of that scope to be initialized before they're needed by any other part of the application, on startup, EJB #Startup for the same effect on EJBs. CDI beans however, don't have that capability out of the box.
The default scope of CDI beans is #Dependent. What this means is that an injected bean inherits the scope of the injection target (except when the bean has its own scope; in that case, its own scope applies). In your case, HelperUtil is not going to live beyond the lifetime of that EJB, sorta like #RequestScoped
Related
how is the #RequestScoped bean instance provided to #SessionScoped bean in runtime here?
Non-lazy instantiation of CDI SessionScoped beans
JSF Named Bean, Eager application scoped (aka #ManagedBean(eager=true) )
I think its constructor is not called until the method is called like helperUtil.dothat(), its not when its containing bean is instantiated.
About all of the injected fields must be initialized by the container when the managed beans are instantiated like the other answer, its true, but all of the injected fields are injected with proxies so they are not the real objects so the real constructors aren't called.
If its constructor is called when its containing bean is instantiated then how about a #RequestScoped bean inside a servlet for example. The servlet is only instantiated one time but the injected #RequestScoped bean must be instantiated multiple times. If its true then surely the #RequestScoped annotation wouldn't work.
So by simply looking at those CDI annotations intention and name like "request" or "session", we know that the real CDI managed bean objects are made/ instantiated independent of the containing user bean instantiation.
Spring creates the class objects by Java dynamic proxies (java.lang.reflect.Proxy). i.e
#Component
public class NewsService implements Service{
}
But how the member variables are injected by Spring? ie
#Autowired
private EntityManager em;
Java dynamic proxies uses interface (i.e Service) to create the objects. But how member variables are injected? The instance variables are not known by interface.
Also when member instances are injected? Load time?(When containing class object is created?) or Lazy loading? (when object is used first?)
Few facts for you:
Spring instantiates specific classes, not interfaces. Dependency injection is done on the original bean instance.
When a proxy is created, Spring registers both the original bean and its proxy in the application context. JDK proxy is created for all interfaces implemented by the original bean.
Proxies are not created if they are not necessary (i.e. no aspect is applied on the target bean).
All beans are eagerly initialized by default. If you want some bean to be instantiated in a lazy fashion, you need to specify it explicitly.
Dependency injection happens right after the bean is instantiated. Some dependencies are injected based on the bean definition, other dependencies might be injected by various bean post processors (but they are executed right away as well).
How is dependency injection realized:
When using XML configuration or autowiring , dependency injection is done via Reflection API. Spring is able to either call property setter (setFoo(...)) or set field value directly (reflection allows setting private members).
When using #Bean methods in Java configuration, dependency injection is done by your method.
A bit on proxies:
JDK proxies and CGLIB proxies are two different proxying mechanisms. JDK creates artificial class based on provided interfaces, whereas CGLIB creates artificial subclass of the target class.
Which proxying mechanism is used depends on your Spring configuration (JDK is the default one). For obvious reasons JDK proxy can be used only in cases when your dependencies are referenced only by interface. From the other side you can not use CGLIB proxying for final classes.
I just incurred in the infamous JavaEE CDI error under GlassFish server:
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001437 Normal scoped bean class ASController is not proxyable because the type is final or it contains a final method public final void ASController.selectPath(org.primefaces.event.NodeSelectEvent) - Managed Bean [class ASController] with qualifiers [#Default #Any #Named].
the error is quite explicative in the fact that he doesn't like final methods inside a CDI bean, however I can't grasp why.
At this link
http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e1429
they explain it is something to do with serialization but I can't see why serializing a class with a final method should be any harder than one with non final methods.
Well, there is several ways in which you can implement a proxy object. But since you expect the proxy to have the "same" type as the proxied bean, you'll have to use inheritance (or demand interfaces which you then could implement, but this would not be an approach where every POJO could be a bean for CDI).
That is, they internally extend from the class you want to inject, generate some proxy code around that and give you that sub class.
This proxy then is handling all the magic to make sure you always have a bean fitting your context (and this bean has all the members variable beans pointing to the just right beans).
So you are not really receiving the type of the bean you want to inject, but a proxy subclass of that bean. This does not work very well with final methods and classes and private constructors.
If the class is not final, the proxy can extend this class, it however cannot easily overwrite the final method of yours. This however may be needed (if e.g your bean is serialized, the proxy needs to deserialize it).
There is, more complicated ways, around that. One could inject this functionality by manipulating the byte code of your class via an agent (e.g removing the final modifiers, inject a default constructor, ...) and maybe even mix this with inheritance, but this is just not implemented, yet (and also non trivial to support over several JVM implementations).
From the linked resource a note indicating that this is planned for a future release:
Note
A future release of Weld will likely support a non-standard workaround
for this limitation, using non-portable JVM APIs:
Sun, IcedTea, Mac: Unsafe.allocateInstance() (The most efficient)
IBM, JRockit: ReflectionFactory.newConstructorForSerialization()
But we didn't get around to implementing this yet.
Container create proxy object for injected classes. So, container doesn't use your classes, but those classes extends. Java prohibit extends final classes, so you cannot use final classes in CDI.