Internals of Spring Framework and other IoC containers - java

I've been using spring for some time, but I always wondered how does it work, more specifically, how do they load and weave beans/classes marked only with an interface or #annotation.
For the xml declarations, it's easy to see how spring preprocesses my beans (they are declared in the xml context that spring reads), but for the classes marked only with annotations, I can't see how that works, since I don't pass any agent to the jvm or so.
I believe there is some Java/JVM hook that allows you to preprocess classes by some sort of criteria, but I wasn't able to found out anything on the docs.
Can someone point me to some docs? Is this related to the java.lang.instrument.ClassFileTransformer API?

Actually by default Spring does not
do any bytecode postprocessing
neither for XML-, nor
annotation-configured beans. Instead
relevant beans are wrapped into dynamic
proxies (see e.g.
java.lang.reflect.Proxy in the
Java SDK). Dynamic proxies wrap the
actual objects you use and intercept
method calls, allowing to apply AOP
advices. The difference is that proxies are essentially new artificial classes created by the framework, whereas weaving/bytecode postprocessing changes the existing ones. The latter is impossible without using the Instrumentation API you mentioned.
As for the annotations, the implementation of <context:component-scan> tag will scan the classpath for all classes with the Spring annotations and create Spring metadata placeholders for them. After that they are treated as if they were configured via XML (or to be more specific both are treated the same).
Although Spring doesn't do bytecode postprocessing itself you can configure the AspectJ weaving agent that should work just fine with Spring, if proxies do not satisfy you.

Related

What is meant by 'There is a type of Spring proxy that can replace the object being returned by the method'?

I am doing a mock exam where I didn't quite understand one of the answers which lacked an explanation of why it was correct.
(Edited from here downward by kriegaex, adding the question from the below comment and some formatting and rephrasing in order to make the text a bit more coherent and readable.)
Question: "Which below statement is true about Spring's proxy feature?"
Answer: "There is a type of Spring proxy that can replace the object being returned by the method."
I understand that Spring AOP can use two types of proxies:
JDK dynamic proxies
CGLIB proxies
In my understanding these are the two type of proxies that are heavily used in Spring. For example when using #Transactional or when creating aspects (#Aspect).
What I understand of the answer given is that they are pointing at the #Around aspect. However, I don't understand why they call it a "type of Spring proxy". Is an aspect a proxy? Thus, is my understanding of an aspect making use of the JDK or the CGLIB proxies incorrect?
The question would be easier to understand if you had provided all possible answers, also the incorrect ones. But given the correct one (which really does sound strange), I can tell you the following:
Both JDK and CGLIB proxies serve the same purpose: to wrap and replace the original objects in order to be able to register some interceptors to their method calls, be it via Spring AOP or other methods.
Yes, both proxy types are used heavily in Spring, JDK proxies for classes implementing interfaces, CGLIB proxies for classes not implementing any interfaces. Optionally, you can configure Spring to use CGLIB proxies also for interface types.
There is no such thing as an "#Around aspect", only an #Around advice type (beside other advice types like e.g. #Before and #After).
No, an aspect is not a proxy. But Spring AOP uses proxies in order to implement its way of doing AOP via delegation pattern, as opposed to AspectJ which does not use any proxies but uses direct bytecode instrumentation to achieve its goal.
Find more information in the Spring documentation.

Some doubts related to the AOP configuration in Spring

I am studying for Spring Core certification and I have a doubt related how Spring handle AOP.
Reading the documentation it seems to understand that exist 2 way to obtain AOP in Java:
Using AspectJ that using byte code modification for aspect weaving offers a full-blown Aspect Oriented Programming language. (so it seems to me that AspectJ is a differnt language that can be integrated with Java to offer it the AOP features).
Spring AOP: used in Spring framework that uses dynamic proxies for aspect weaving instead the bytecode modification.
So my doubts are mainly the followings:
1) Reading the documentations found the following method to add the AOP support to my Spring application:
USING JAVA CONFIGURATION CLASS:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan(basePackages=“com.example”)
public class AspectConfig {
...
}
USING XML CONFIGURATION:
<beans>
<aop:aspectj-autoproxy />
<context:component-scan base-package=“com.example” />
</beans>
As you can see in both configurations there is a reference to AspectJ:
#EnableAspectJAutoProxy
and
<aop:aspectj-autoproxy />
Why? If Spring use Spring AOP instead AspectJ why there is a reference to AspectJ when I configure AOP in Spring?
2) In the previous examples are show 2 way to configure Spring: by Java configuration class and by XML configuration. I know that exist a third way to configure a Spring application: by the use of annotations. So exist a way to configure AOP using the annotations?
I think that these Spring AOP settings with references to AspectJ in their names are indeed more irritating than helpful. I can understand why you are confused. Spring AOP is really a different concept from AspectJ. As you said: dynamic JDK or CGLIB proxies in Spring AOP versus byte code instrumentation during compile or load time in AspectJ. Other differences are:
AspectJ compile-time weaving needs a special compiler called Ajc. It is basically an Eclipse Java compiler Ecj enhanced by the aspect weaver which does the instrumentation. In contrast, Spring AOP creates dynamic proxies during runtime.
In AspectJ there are two syntax variants: native and annotation-based. The former is more elegant and expressive, a superset of Java and definitely needs Ajc to be compiled. The latter uses Java annotations and can be compiled with Javac, but needs the aspect weaver contained both in Ajc (compile time) and in the weaving agent aspectjweaver.jar (load time) to "finish" them and make them usable during runtime. Both variants need the AspectJ runtime contained in both aspectjrt.jar (very small, used for compile-time-woven aspects during runtime) and aspectjweaver.jar (much bigger, used for load-time weaving, contains both the runtime and the weaver).
AspectJ works for any Java class, it does not need or even know about the Spring framework. Spring AOP needs the Spring framework as a foundation, you can only instrument Spring Beans/Components with it, not Spring-agnostic POJOs.
AspectJ is more efficient because it avoids proxies. But Spring AOP is an optional part of the Spring framework anyway, so if you use Spring and method execution interception of Spring Beans is all you need, it makes perfect sense to use it.
Spring AOP uses a subset of the AspectJ pointcut syntax. Maybe this is the subtle reason why Spring AOP uses AspectJ references, but I still think it was a bad decision to not differentiate the two concepts from one another more clearly with regard to nomenclature. Besides, the common poinctut language subset is defined in a little JAR called aopalliance.jar because long ago a so-called "AOP Alliance" has defined that syntax. The dominating and by far most powerful AOP language today is AspectJ, though, so in reality AspectJ (maintained by Eclipse) is the leader in that area, IMO.
When I say that Spring AOP uses a subset of AspectJ syntax, conversely it means that AspectJ offers a superset. There are more pointcut types such as call(), set(), get() etc. and you have way more options to intercept joinpoints and apply cross-cutting concerns to your code base via advice or inter-type definition.
I do not understand your question #2. The configuration class in your example does use annotations, so there is no third way. ;-) But there is an old, really outdated AOP approach in Spring called interceptors. It is a leftover of an early AOP approach and kind of obsolete nowadays, even though it is still usable.
Both Spring AOP and AspectJ can be configured via XML or annotations within Spring. :-)
Not sure if I completely understand your question, I think you are asking something like: "If I'm using Spring AOP, why do I see references to AspectJ?"
If that's the case, you should know that Spring is not in competition with AspectJ, but rather leverages AspectJ for AOP.
See Spring documentation: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html

Java Dependency Injection with Multiple Implementations

My question: is there a way to use javax.inject (or any other Java injection framework) for a consumer of a Provider to use multiple implementations at runtime if the number of implementations is unknown at build time?
Some background on my need for this: I work on reusable frameworks which, for the most part, combine the use of a factory and a service locator to load implementations. Several of these seem like they could be reworked to use proper dependency injection, at least insofar as removing the service locator, but there are some that require loading all implementations found on the class path. This is achieved through a simple "multi-implementation" implementation which then loads the other implementations, saving the instances off in a collection and looping over them when the API is called.
I assume you are running on the Java SE platform (as opposed to a Java EE platform) in which case I would highly recommend HK2 (see https://hk2.java.net/2.2.0/). It has a lot of support for efficiently instantiating services and it is certainly the case that multiple implementations of the same contract can be available at runtime. Then at runtime there are a whole manner of mechanisms that you can use to choose which particular implementation will satisfy the dependency (i.e., service ranking or assisted injection etc)
For build time with hk2 you can create "inhabitant" files that describe services to the point where they can be satisfied at runtime without classloading all of them (only the one that is picked will be classloaded if you do it properly). This can be a huge performance boost at boot time of your application (if that sort of thing matters to you).
If you are running on a Java EE platform you can also use HK2, but you should then also give a long look at CDI. Both CDI and HK2 are implementations of JSR-330, and so both work with javax.inject API
So you basically have one implementation that delegates a call to an API method to all other implementations. you will need to inject this bean in all the dependencies you can do this in spring by giving this bean (this implementation instance) an id and then inject it using #Autowired #Qualifier("bean_id"). now for listing all implementations that can be done easily in spring by injecting an applicationContext into your delegate implementation and then querying the applicationContext for all beans implementing the API interface.

how do java annotations work with spring, are they scanned at runtime or at startup?

Just trying to understand how Java annotations work under the covers.
Seeing as spring relies on annotations and scanning the object graph for DI and AOP (reflection), curious how things actually work.
With spring, are all lookup mappings etc. done at startup, so at runtime spring looks at its own inner mappings for DI/AOP/etc. instead of scanning the entire object graph?
Performance wise, if what I am guessing above is correct, it is basically performing a hash lookup?
Spring scans classes in the specified package when <context:component-scan> is present in the config.
Otherwise, Spring only looks at the annotations of classes explicitly declared in the config.
It is not true that Spring "relies" on annotations. Configuring your classes via annotations is just one option, using XML or other configuration files is another.

Runtime dependency injection with Spring

My current project is leveraging Spring, and our architect has decided to let Spring manage Services, Repositories and Factory objects, but NOT domain objects. We are closely following domain driven design. The reasoning behind not using spring for domain objects is primarily that spring only allows static dependency injection. What i mean by static dependency injection is that dependencies are specified inside xml configuration and they get "frozen".
I maybe wrong, but my current understanding is that even though my domain only leverages interfaces to communicate with objects, but spring's xml configuration forces me to specify a concrete dependency. hence all the concrete dependencies have to be resolved at deployment time. Sometimes, this is not feasible. Most of our usecases are based on injecting a particular type based on the runtime data or a message received from an end user.
Most of our design is following command pattern. hence, when we recieve a command, we would like to construct our domain model and based on data received from a command, we inject particular set of types into our aggregate root object. Hence, due to lack of spring's ability to construct a domain model based on runtime data, we are forced to use static factory methods, builders and Factory patterns.
Can someone please advise if spring has a problem to the above scenario ?
I could use AOP to inject dependencies, but then i am not leveraging spring's infrastructure.
I suggest you read the section in the Spring docs concerning Using AspectJ to dependency inject domain objects with Spring.
It's interesting that you said "I could use AOP to inject dependencies, but then i am not leveraging spring's infrastructure, " considering that AOP is a core part of Spring's infrastructure. The two go very well together.
The above link allows you to have Spring's AOP transparently inject dependencies into domain objects that are creating without direct reference to the Spring infrastructure (e.g. using the new operator). It's very clever, but does require some deep-level classloading tinkering.
Spring's dependency injection/configuration is only meant for configuring low-level technical infrastructure, such as data sources, transaction management, remoting, servlet mount-points and so forth.
You use spring to route between technical APIs and your services, and inside those services you just write normal Java code. Keeping Spring away from your domain model and service implementations is a good thing. For a start , you don't want to tie your application's business logic to one framework or let low-level technical issues "leak" into your application domain model. Java code is much easier to modify in the IDE than spring's XML config, so keeping business logic in java let's you deliver new features more rapidly and maintain the application more easily. Java is much more expressive than spring's XML format so you can more clearly model domain concepts if you stick to plain Java.
Spring's dependency injection (and dependency injection in general) is basically for wiring together Services, Repositories and Factories, etc. It's not supposed to directly handle things that need to be done dynamically in response to commands, etc., which includes most stuff with domain objects. Instead, it provides control over how those things are done by allowing you to wire in the objects you want to use to do them.

Categories