Am I allowed to declare a lifecycle interceptor on an interceptor? - spring

I have my business bean defined thus:
#Local
#Interceptors(BusinessInterceptor.class})
public class MyBean implements SomeBean { ... }
And then I want my BusinessInterceptor to be configured with Spring's SpringBeanAutowiringInterceptor:
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class BusinessInterceptor {
#Autowired
private SomeSpringBean someSpringBean;
}
Is this allowed/legal? I'm getting errors (NPEs, mostly) suggesting that the fields in BusinessInterceptor have not been initialized properly.

I doubt this can work. If I understand well your scenario, you have basically two DI containers, one is Spring and the other the app. server itself. Each one manages different elements. The BusinessInterceptor is created by the app. server which is unaware of Spring -- the #Autowired bean is then not set.
( Note that Spring and EJB3 have become quite similar now. You can have the same functionalities as EJB with Spring. Spring has indeed declarative transactions, dependency injection and AOP facilities similar to EJB3 interceptors (these are the main managed features). On the other hand, EJB3 is now so lightweight that there isn't really a compelling reason to use Spring with with EJB3. See Future of enterprise Java: full stack Spring or full stack Java EE. But this does not answer the question, and is just a little digression of mine :)

Related

Spring #Transactional - synchronize via AspectJ

I am trying to synchronize declarative transactions (i.e. methods annotated with #Transactional) using AspectJ like so:
...
import org.aspectj.lang.annotation.Aspect;
...
#Component
#Aspect
public class TransactionMonitor extends TransactionSynchronizationAdapter {
#Before("execution(#org.springframework.transaction.annotation.Transactional * *.*(..))")
private void registerTransactionSynchronizationOnAnnotation(JoinPoint joinPoint) {
TransactionSynchronizationManager.registerSynchronization(this);
}
}
This currently fails with java.lang.IllegalStateException: Transaction synchronization is not active which indicates that the synchronization is not run inside the transaction execution, but before. I want to ensure that this is the other way round, of course.
I found this answer, however #Order(Ordered.LOWEST_PRECEDENCE) had no effect, and
#DeclarePrecedence(
"org.springframework.transaction.aspectj.AnnotationTransactionAspect, xxx.xxx.TransactionMonitor, *"
)
led to this during startup:
java.lang.IllegalArgumentException: DeclarePrecedence not presently supported in Spring AOP
I have the feeling this is AOP and AspectJ not being happy with each other, but I am not sure. I am thankful for any ideas.
EDIT: I have to use #EnableTransactionManagement(proxyTargetClass = true), can this be related to the issue?
For #DeclarePrecedence you need to switch to native AspectJ. Spring AOP is just "AOP lite" and technologically has little in common with AspectJ other than its syntax which is basically an AspectJ subset. The Spring manual describes how to use native AspectJ in Spring via LTW (load-time weaving). Precedence declaration for Spring components rather works using #Order, BTW.
I am not a Spring user at all, but as for declarative transaction management, it already knows proxy-based Spring AOP versus native AspectJ mode, see EnableTransactionManagement.mode and the enum constants in AdviceMode. Besides, EnableTransactionManagement also has an order property. Reading Javadoc and the Spring manual helps, I guess.

Is it ok to use non-annotated classes (beans) in spring framework?

I have a spring-boot project. Some of the classes I am using it in the 'spring' way, meaning that they are annotated by "#Service", "#Repository", "#Autowired". At the same time, I have lots of classes, which are only used in the normal Java way, meaning that there are no any Spring annotations, and they are created in the standard way of constructing an object in a constructor.
For example, one of the non-annotated classes is:
public class GenericTree<T>
{
private GenericTreeNode<T> root;
public GenericTree ()
{
root = null;
}
public GenericTreeNode<T> getRoot ()
{
return this.root;
}
public void setRoot (GenericTreeNode<T> root)
{
this.root = root;
}
...
}
Is it OK or normal to have a mixure of classes with or without Spring annotations? Probably, I could convert all non-annotated classes into annotated classes by using Spring's annotation markers. Does that really benefit or is it necessary?
BTW, my application's main logic and functions are not web-centric, although they are created as a Spring project. The reason I created in Spring is I want to provide a restful service for my interface so that I can easily test in browser in development, and others can use it with Restful service.
Yes it is ok.
Keep in mind that annotations are not Spring exclusive. Annotations were introduced in Java 5 and they are just meta data for your Java code. This meta data can be useful at:
Compile time
Build time
Runtime
You can even create your own custom annotations and annotate your code with them.
Spring framework comes with some annotations and each one of them has its purpose, but that doesn't mean you have to annotate all your classes with Spring annotations when you are using this framework.
When you annotate your classes as Spring Beans, they become part of the Spring Application Context, thus making them available to be injected with the #Autowired annotation (Spring framework is based on the dependency injection design pattern). But Spring annotations have other implications too, I cannot go into the detail of each one of them but for example, you have to consider that the default scope of annotations like #Bean, #Component, #Controller, #Repository, #Service is Singleton. So whenever you annotate a class with one of these annotations and you don't define a scope, what you get is a singleton class shared all over your application. Other scopes are:
singleton
prototype
request
session
application
websocket
Taking in consideration your GenericTree class, does it make sense to annotate an abstract data structure class as a Spring Bean? Probably not.
So yes, when you develop an application based on Spring framework the normal thing is to have a mixture of Spring annotated classes and regular POJO's.
I recommend you to read the Spring framework documentation, learn what dependency injection is and the purpose and implications of the most used Spring annotations.

Injecting spring beans into legacy web app POJOs [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
In order to provide POJOs in my legacy web app (Tomcat 8.0.26) with the ability to send ActiveMQ messages I've taken the recommendation to introduce Camel (2.15.2) / Spring (4.2.1) into the app to purely for the purpose of managing pooled MQ connections. I'm hoping there isn't an easier way.
Doing things the Spring way I'm thinking everything would need to be based around an MVC architecture with HTTP servlet aware controllers having access to the servlet context and therefore the Spring context in order to inject beanFactory beans into classes annotated with #Controller and #Service (and in fact there must be a Spring #Controller class that enables Spring to inject the #Service class.
However, as I've stated this is legacy code that will not be using the spring web framework.
After much pain it seems that the only way I can get beanFactory beans injected into my POJOs is to go the AspectJ and Weaving route. Before I go down this road can someone tell me that this is currently the best approach (what I've read describing this solution is from 2011 Can't get Spring to inject my dependencies - Spring Newbie) ? Can you point me to documentation and a working example?
Many thanks.
1) aspectj with #Configurable
In your #Configuration annotated class/es
you can add some more annotations
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableSpringConfigured
#EnableAspectJAutoProxy
to enable aspectj and the #Configurable annotation,
you need to import the aspectj lib to your project and add the spring tomcat instrumentable java agent in your tomcat lib folder (give a look here, it exaplains how to configure tomcat) http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html
this is not going to help you if you are going to create your pojos using "new"
MyPojo p = new MyPojo(); // no black magic for this, you will need to satisfies the dependencies yourself) but that would be helpful for example when you load some entities through a framework like hibernate and you want to inject something into them.. #Configurable it's an option that can be evaluated in those cases, for what you describe I would rather not use it.
2) You can have some static methods that uses some static set spring-beans and use them from your pojos, something like
class Util{
private static SprintBeanWithJmsSupport x;
public static setSpringBeanToHandleJmsMessages(SprintBeanWithJmsSupport x){
Util.x = x;
}
public static sendJmsMessage(JmsMessage m){
x.sendMessage(m)
}
}
and you can go with Util.sendJmsMessage(...)
this is a bit shitty but it does the work, I don't personally like this approach
3) set your spring beans in your pojo when they need to use them (maybe behind some nice interfaces that suit your domain)
if you go with spring mvc you will likely end up having some controllers that will use some services (generally they handle security / db access and are the entry point to start the "use cases"), as everything wthin these layers is handled by spring it will be very simple to pass the spring-bean to handle jms messaging to your pojos, this seems to me quite a nice way to handle the problem
I went mostly based on memory and something may not be completely accurate, plus my english is .. what it is, so hope this can be helpful anyway.

Dynamic dependency injection in jsf 2 or spring 3

I have 3 implementations of an interface, and in order to instantiate one of them I need to check a parameter from the database.
I was planning to do it with the factory pattern, but since I'm using JSF 2 dependecy injection in the rest of my application I was wondering if
there's a way to do that, is it possible to do the dependency injection dinamically?
can I indicate somehow a method or something to pick up the correct implementation at each moment?
For the backend I'm using spring core, so a way to do that with the spring context would work to.
I'm using Annotations for everything (#Autowired for Spring, #ManagedProperty for JSF).
EDIT: The project will be deployed on a Tomcat server.
I suggest you to use CDI in your JSF project, you can then use programmatic injection.
You should start with adding CDI Qualifiers to your interface implementations (you will basically create custom annotation for each implementation - tutorial). Then you can use something like
#Named //similar to ManagedBean
#RequestScoped
public Bean {
#Inject
#Any
Instance<YourInterface> yourInterface;
public void someMethod() {
if(someCondition) {
InterfaceImpl impl = yourInterface.select(new SomeOfYourQualifiers()).get();
}
}
}
Source
Also you you don't have to use Autowired in favour of Inject. I am also sure that there is some Spring way how to to this but I will leave that to some Spring expert here:-)
EDIT
According to this answer is really possible to run CDI on Tomcat. You will also find some tutorials like this one. And Spring approach could be using AutowireCapableBeanFactor but as I say, I don't know Spring much so it's just a wild gues:-)

Best Practise of injecting applicationContext in Spring3

As in the title above, I am confused about pros cons between injecting applicationContext by directly #Autowired annnotation or implementing ApplicationContextAware interface in a singleton spring bean.
Which one do you prefer in which cases and why? Thanks.
Actually, both are bad. Both of them tie your application to the Spring framework, thus inverting the whole inversion-of-control concept. In an ideal world, your application should not be aware of being managed by an ApplicationContext at all.
Once you have chosen to violate this principle, it doesn't really matter how you do it. ApplicationContextAware is the legacy version that has been around at least since Version 2.0. #Autowired is a newer mechanism but they work in pretty much the same way. I'd probably go with ApplicationContextAware, because it semantically makes clear what it is about.
As #Sean Patrick Floyd says, the need of ApplicationContext is often due to a bad design. But sometimes you have no other option. In those cases I prefer the use of #Autowired because is the way I inject all other properties. So, if I use #Autowired for injecting MyRepository, why can't I use it for ApplicationContext or any other Spring bean?
I use Spring interfaces only for those things I can't do with annotations, for example BeanNameAware.
If you need to get a prototype in a singleton then you can use method injection. Basically, you create an abstract method that returns the object you need and spring will return the prototype everytime you call that method. You define the "lookup-method" in your spring config. Here are some links:
http://docs.spring.io/spring/docs/1.2.9/reference/beans.html#beans-factory-method-injection
http://java.dzone.com/articles/method-injection-spring
Since you are not extending any of the spring classes your application is always separated from the framework. Most of the cases you will not wanted to inject the ApplicationContext as it, but will need to inject the beans defined in the ApplicationContext.
The best case is always to stick to the bare minimum, until and unless you have any specific requirement and this is very simple with spring.
So either,
Annotate your beans and scan them in application context, then use #Autowire to wire them up.
Use application context to wire your bean expediencies(old xml style configs). You can use #Autowire with this approach also.
When you want to control the bean life cycle, you can read the API and customize it, but most of the time these general settings will do the job.
Here are some examples.
Spring Auto-Wiring Beans with #Autowired annotation
Spring Auto-Wiring Beans XML Style
Spring IoC container API Docs
There is no need to use ApplicationContext at all.
ObjectFactory
If you need to use prototype scoped beans in a singleton bean, inject an org.springframework.beans.factory.ObjectFactory.
For example using constructor injection:
#Service
class MyClass {
private ObjectFactory<MyDependency> myDependencyFactory;
public MyClass(ObjectFactory<MyDependency> prototypeFactory) {
myDependencyFactory = prototypeFactory;
}
}
Why
Now what's the benefit over using ApplicationContext ?
You can substitute this dependency (e.g. in a test) by simply passing a lambda (since ObjectFactory is a #FunctionalInterface) that returns a stubbed version of it.
While it is possible to stub the ApplicationContext, it is not clear in that case which beans will be looked up and need to be stubbed.

Resources