Understanding basic Spring Framework and Total Flow - spring

I am new to the Spring Framework. Please guide me regarding basic understanding of Spring. I know Java and JSF, but I don't know anything about Struts or other frameworks. I have searched the Internet and was able to download a PDF, but I don't understand the Spring flow like I understand JSF flow. Please provide me with links for a simple way to understand Spring's flow.

Transition 1 – User sends request to server by submitting form / by
clicking hyperlink etc. Request is initially given to WEB.XML.
Transition 2 – WEB.XML routes request to DispatcherServlet by looking
at tag.
Transition 3 – Inside DispatcherServlet,
First ‘HandlerMapping’ handed over request to suitable ‘Controller’.
Transition 4 – Controller maps request to proper Model class. All
BUSINESS LOGIC is done inside Model class.
Transition 5 – If database
operation is needed then Model class will route request to suitable
DAO. All database operations should be carried out in DAO.
Transition6 – If needed then attach attributes into request/session/application
scope and return back to Model.
Transition 7 – If needed then attach
attributes into request/session/application scope and return back to
Controller.
Transition 8 – Controller simply returns it to any View
(JSP/HTML etc).
Transition 9 – JSP/Html is viewed back to user.
Spring MVC Application Flow:

I'm new to Spring Framework too.
Up to now, the document below is the most basic one. I'm reading it as well, hope it could help you.
Introduction to Spring Framework

I am new to Spring too and time ago had similar question. First of all I want to recommend you 'Spring in Action' book by Craig Walls, I found it very usefull and easy to understand, also
http://www.tutorialspoint.com/spring/ helped me to figure many things out. If I understood your question right, then we can divide “Spring's flow” into Spring IoC container's and Spring bean's life cycles. Here is very small overview with exapmle on Spring bean's life cycle. A bean goes through several steps between creation and destruction in the Spring
container. These steps are:
Instantiate
Populate properties
BeanNameAware`s setBeanName()
BeanFactoryAware`s setBeanFactory
ApplicationContextAware`s setApplicationContext()
Pre-initialization BeanPostProcessors
InitializingBean`s afterPropertiesSet()
Call custom init-method
Post-initialization BeanPostProcessors
DisponsableBean`s destroy
Call custom destroy-method
Each step provides own oportunities for customization. Here is some code which simply “traces” bean`s life:
For bean ClassA:
public class ClassA implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware{
private String messageA;
public ClassA() {
System.out.println("ClassA: default constructor called.");
}
public void customInitMethod(){
System.out.println("ClassA: customInitMethod() method called.");
}
public void customDestroyMethod(){
System.out.println("ClassA: customDestroyMethod() method called.");
}
public String getMessageA() {
System.out.println("ClassA: message get method called.");
return messageA;
}
public void setMessageA(String message) {
System.out.println("ClassA: message set method called.");
this.messageA = message;
}
public void afterPropertiesSet() throws Exception {
System.out.println("ClassA: afterPropertiesSet() called because InitializingBean interface.");
}
public void destroy() throws Exception {
System.out.println("ClassA: destroy() called because DisposableBean interface.");
}
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
System.out.println("ClassA: application context set: " + arg0.getApplicationName());
}
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("ClassA: beanFacrory set.");
}
public void setBeanName(String arg0) {
System.out.println("ClassA: bean name set: " + arg0);
}
}public class ClassA implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware{
private String messageA;
public ClassA() {
System.out.println("ClassA: default constructor called.");
}
public void customInitMethod(){
System.out.println("ClassA: customInitMethod() method called.");
}
public void customDestroyMethod(){
System.out.println("ClassA: customDestroyMethod() method called.");
}
public String getMessageA() {
System.out.println("ClassA: message get method called.");
return messageA;
}
public void setMessageA(String message) {
System.out.println("ClassA: message set method called.");
this.messageA = message;
}
public void afterPropertiesSet() throws Exception {
System.out.println("ClassA: afterPropertiesSet() called because InitializingBean interface.");
}
public void destroy() throws Exception {
System.out.println("ClassA: destroy() called because DisposableBean interface.");
}
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
System.out.println("ClassA: application context set: " + arg0.getApplicationName());
}
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("ClassA: beanFacrory set.");
}
public void setBeanName(String arg0) {
System.out.println("ClassA: bean name set: " + arg0);
}
}
For CustomPostProcessor:
public class CustomPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("CustomPostProcessor: beforeInitialization on: "
+ beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("CustomPostProcessor: afterInitialization on: "
+ beanName);
return bean;
}
}
In main class we creating ApplicationContext, getting bean and printing message out:
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext(
"META_INF/spring/app-context.xml");
ClassA objA = (ClassA) context.getBean("classA");
System.out.println(objA.getMessageA());
context.registerShutdownHook();
}
In app-context.xml we have:
<bean id="classA" class="ClassA" init-method="customInitMethod"
destroy-method="customDestroyMethod">
<property name="messageA" value="messagA: Hello Spring!" />
</bean>
<bean class="CustomPostProcessor" />
As I understand output lines correspond to life cycle stages this way:
1.Instantiate
ClassA: default constructor called.
2.Populate properties
ClassA: message set method called.
3.BeanNameAware`s setBeanName()
ClassA: bean name set: classA
4.BeanFactoryAware`s setBeanFactory
ClassA: beanFacrory set.
5.ApplicationContextAware`s setApplicationContext()
ClassA: application context set:
6.Pre-initialization BeanPostProcessors
CustomPostProcessor: beforeInitialization on: classA
7.InitializingBean`s afterPropertiesSet()
ClassA: afterPropertiesSet() called because InitializingBean interface.
8.Call custom init-method
ClassA: customInitMethod() method called.
9.Post-initialization BeanPostProcessors
CustomPostProcessor: afterInitialization on: classA
Program prints message
ClassA: message get method called.
messagA: Hello Spring!
10.DisponsableBean`s destroy
ClassA: destroy() called because DisposableBean interface.
11.Call custom destroy-method
ClassA: customDestroyMethod() method called.

Related

#Autowired works but not #Inject

I have a Resource which injects the following class
#Component
public class CustomDozerBeanMapper implements Mapper {
private final DozerBeanMapper beanMapper;
public CustomDozerBeanMapper() {
this.beanMapper = new DozerBeanMapper();
BeanMappingBuilder builder = new BeanMappingBuilder() {
protected void configure() {
//some mapping stuff
}
};
beanMapper.addMapping(builder);
}
#Override
public <T> T map(Object o, Class<T> aClass) throws MappingException {
return beanMapper.map(o, aClass);
}
#Override
public void map(Object o, Object o1) throws MappingException {
beanMapper.map(o, o1);
}
#Override
public <T> T map(Object o, Class<T> aClass, String s) throws MappingException {
return beanMapper.map(o, aClass, s);
}
#Override
public void map(Object o, Object o1, String s) throws MappingException {
beanMapper.map(o, o1, s);
}
}
In my applicationContext.xml I have declared
<context:annotation-config/>
<context:component-scan base-package="foo.bar"/>
<bean id="customDozerMapper" class="foo.bar.CustomDozerBeanMapper" />
Then in our resource I inject it
class SomeResource {
#Inject CustomDozerMapper customDozerMapper;
//We have loads of other Injects which work just fine, only this class has problems
}
Caused by: A MultiException has 1 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=CustomDozerBeanMapper,parent=SomeResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1098507248)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:947)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:975)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:965)
at org.glassfish.jersey.server.spring.SpringComponentProvider$SpringManagedBeanFactory.provide(SpringComponentProvider.java:191)
at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:153)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:70)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:761)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:700)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
Now if I change and use #Autowired, it works fine
We are using Spring for dependency management, but for some reason h2k is being used, and I get the following exception
Can anyone please explain what the problem might be?
Why does it work with #Autowired and not #Inject
Why is h2k being used, and not Spring?
Probably, the problem may be because of 2 bean declarations (one in the XML configuration and the another one with #Component) and a DI container couldn't able to pick up one of them.
All solutions that are available here:
removing one of the bean definitions (I'd prefer the XML one)
specifying a bean by the #Qualifier or #Named annotation
The problem might also be due to the bean name in config file customDozerMapper and actual injection customerDozerMapper are not matching. If #inject does not find matching bean, it throws an exception. However, there is provision for #autowired wherein you can set attribute required=false and it injects null if it does not find matching bean.
Note: Configuration in config xml overrides the annotation
configuration.

Spring rabbit: Intercept method calls annotated with #RabbitListener without AspectJ usage

Is there a way to intercept calls of bean methods annotated with #RabbitListener without using AspectJ.
The code is something like this
#OtherAnnotation
#RabbitListener
public void do(Message message)
I need to intercept all calls to #RabbitListener method, if the method has #OtherAnnotation annotation.
UPDATE:
I managed to make it work using Gary Russell solution.
public class CustomRabbitListenerAnnotationBeanPostProcessor extends RabbitListenerAnnotationBeanPostProcessor {
#Override
protected void processAmqpListener(RabbitListener rabbitListener, final Method method, Object bean, String beanName) {
if (method.isAnnotationPresent(OtherAnnotation.class)) {
ProxyFactory proxyFactory = new ProxyFactory(bean);
proxyFactory.addAdvisor(new StaticMethodMatcherPointcutAdvisor(new OtherAnnotationInterceptor()) {
#Override
public boolean matches(Method advisorMethod, Class<?> targetClass) {
return advisorMethod.equals(method);
}
});
Object proxiedBean = proxyFactory.getProxy();
super.processAmqpListener(rabbitListener, method, proxiedBean, beanName);
} else {
super.processAmqpListener(rabbitListener, method, bean, beanName);
}
}
}
The bean definition is like:
#Bean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
public CustomRabbitListenerAnnotationBeanPostProcessor customRabbitListenerAnnotationBeanPostProcessor() {
return new CustomRabbitListenerAnnotationBeanPostProcessor();
}
It's a bit ugly, but it works. If anyone has better solution, please share it.
You can subclass RabbitListenerAnnotationBeanPostProcessor and override the processListener method and modify the bean before invoking the super version.
Then, replace the RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME bean registered by the #EnableRabbit with your subclass.
Or, simply add your advice to the container factory's advice chain and all listeners will be advised. You can then do a runtime check to see if the other annotation is present.
i think what you are looking for is a bean-post-processor
heres a simple example:
https://www.tutorialspoint.com/spring/spring_bean_post_processors.htm
if you need to intercept calls you can wrap a proxy over the returned instance. a good example is the org.springframework.validation.beanvalidation.MethodValidationPostProcessor. you can probably extend org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor as well.
EDIT i am just learning this myself so i hope that is the right way to do this but this worked for me when experimenting with it
#Component
public class MyInterceptAnnotationBeanPostProcessor
extends AbstractBeanFactoryAwareAdvisingPostProcessor
implements InitializingBean {
public void afterPropertiesSet() {
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(
null,
MyIntercept.class);
this.advisor = new DefaultPointcutAdvisor(pointcut, this.createAdvice());
}
protected Advice createAdvice() {
return new MethodInterceptor() {
#Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("advice");
return arg0.proceed();
}
};
}
}

Why would Spring autowire fail?

#Service
public class LogProcessorServiceImpl {
#Autowired
private static ApplicationConfigurationService applicationConfigurationService;
public static void processPageRequestsLogs() {
if(applicationConfigurationService==null) {
System.out.println("autowire failed");
}
I have the ApplicationConfigurationService service autowired like this all over the place and it works fine. The package of this class is being scanned so that's not the problem. It might be related to the way this particular method is called. I have a servlet that is loaded after all other servlets and it fires of a timer that executes the method above with 60 second delay. I assume all autowiring should be completed.
public class ProcessSchedulerServlet implements javax.servlet.Servlet {
Timer timer=new Timer();
#Override
public void init(ServletConfig arg0) throws ServletException {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
LogProcessorServiceImpl.processPageRequestsLogs();
}
}, 60*1000, 120*1000);
}
Here's what happens as soon as I true to use ApplicationConfigurationService:
autowire failed
Exception in thread "Timer-1" java.lang.NullPointerException
at com.siteadmin.services.impl.LogProcessorServiceImpl.processPageRequestsLogs(LogProcessorServiceImpl.java:39)
at com.siteadmin.servlets.ProcessSchedulerServlet$1.run(ProcessSchedulerServlet.java:20)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
=== 2012-11-18 ============================================================
See also: How to go about Spring autowiring?
You can't autowire static fields in Spring, this is discussed here
As alternative, if your LogProcessorServiceresides in the root web application context, you can
autowire it with Spring WebApplicationContextUtils utility class.
public class ProcessSchedulerServlet implements javax.servlet.Servlet {
Timer timer=new Timer();
#Autowired
LogProcessorService logProcessorService;
#Override
public void init(ServletConfig arg0) throws ServletException {
WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
final LogProcessorService svc = this.logProcessorService;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
svc.processPageRequestsLogs();
}
}, 60*1000, 120*1000);
In general, you should avoid using Java singletons, where using Spring singletons is enough.
Also, if you declared LogProcessorServiceImpl with a #Service annotation, that implies it to be a Spring singleton, so you should not use static fields there at all.
P.S. this answer is about autowiring, it assumes that the idea with TimerTask is correct, in the real apps consider using the Spring Scheduling API

Trigger a second advised method from a method already being advised in Spring

I have a Class, call it X, in this class I have successfully advised a method call it method(){} from an Annotated Spring.
So, here it is:
public class X {
public void method(){...}
public void method2(){...}
}
Here is my aspect, shortened of course:
#Aspect
public class MyAspect{
#Pointcut("execution(* X.method(..))")
public void methodJP(){}
#Pointcut("execution(* X.method2(..))")
public void method2JP(){}
#Around("methodJP()")
public void doMethodJP(ProceedingJoinPoint pjp) throws Exception {
pjp.proceed(); //Amongst other things!!!
}
#After("method2JP()")
public void doMethod2JP(JoinPoint jp) throws Exception {
//Do some stuff here
}
}
Now... both join points work well, however, I within my X.method, I also call the method that is advised by method2JP()... and of course, my method2JP does not get triggered.
Is there any way I can get this to work?
Thanks.
Since Spring AOP works by proxying classes, for the advice to be invoked, you must call the method through the proxy or wrapper supplied by the bean factory.
If you don't want to break out into multiple classes, you can have the method retrieve a the proxied version of "itself" from the beanfactory. Something like this
#Service
public class MyService {
#Autowired
ApplicationContext context;
public void method1() {
context.getBean(MyService.class).method2();
}
public void method2() {
}
}
This will guarantee that the invocation of method2 from method1 will apply any aspects on the method2 pointcut.
methodJP() should be declared in another class. In the regular scenario the aspects are not triggered when you invoke a method from within the same object.

Why in destroy method is not called automatically in below when object will destroy?

public class Instrumentalist implements Performer, InitializingBean, DisposableBean {
private Instrument instrument;
private String song;
public void setInstrument(Instrument instrument)
{
this.instrument=instrument;
}
public void setSong(String song)
{
this.song=song;
}
public void afterPropertiesSet() throws Exception
{
System.out.println("Before Playing Instrument");
}
public void destroy() throws Exception
{
System.out.println("After Playing Instrument");
}
public void perform() {
// TODO Auto-generated method stub
System.out.println("Playing "+ song + " : ");
instrument.play();
}
}
In above example only i got the out put in which afterPropertiesSet() is called but not destroy method. Below is my config.xml
<bean id="dhiraj" class="Instrumentalist">
<property name="song" value="Sa Re Ga Ma" />
<property name="instrument" ref="piano" />
</bean>
<bean id="piano" class="Piano" />
and i called from my main method as below -
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml");
Performer performer1=(Performer)context.getBean("dhiraj");
performer1.perform();
Try this:
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml");
//...
context.close(); //!!!
You have to close the context manually, otherwise Spring does not know that the bean is no longer needed and should be destroyed. Note that you have to use AbstractApplicationContext type as ApplicationContext interface does not define close().
For singleton beans like dhiraj, the destroy() lifecycle method will be called when, and only when, the application context is shut down.
If your code fragment is the entirety of your program, then destroy() will not be called because you're not closing the context properly.
Add context.close() to the end of your fragment, and you'll see destroy() being called.
You need to close Context Object,Then Only destroy method is called.Check for img
ConfigurableApplicationContext Context= new ClassPathXmlApplicationContext("ApplicationContext.xml");
//.............
//.........
Context.close();
**
You can also register shutdown hook this way:
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml");
context.registerShutdownHook();

Resources