Inrecept requests to specific beans - java

I'm developing webapp using spring 3 mvc and using annotation-based controllers. I want to define an interceptor, that will intercept requests to specific beans not for all. How I can do that?
Now i use following config, but it intercept requests to all beans
<bean id="annotationMapper" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="sessionInterceptor"/>
</list>
</property>
</bean>
<bean id="sessionInterceptor" class="app.interceptors.SessionCheckInterceptor"/>
Thanks!

In Spring 3 you can bind interceptors to specific URLs using mvc namespace:
<mvc:interceptors>
<mvc:interceptor>
<bean class="app.interceptors.SessionCheckInterceptor" />
<mvc:mapping path = "/somePath/**" />
</mvc:interceptor>
</mvc:interceptors>
For more complex cases you may also use AOP to intercept controller method calls.

I think the best choice for intercepting calls to your bean is using Spring AOP.
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}

I have found a solution using springplugins project (http://code.google.com/p/springplugins/)
It define two own mappers:
SelectedAnnotationHandlerMapping handle only defined url's
IgnoreSelectedAnnotationHandlerMapping handle all urs's except defined
If you know a better way to solve this problem, you a welcome

Related

How to create java.util.Optional<T> object from Spring bean?

Java
public class MyObject{}
public class MyFactory{
private Optional<MyObject> myproperty;
public Optional<MyObject> getMyproperty{...}
public void setMyproperty{...}
}
Spring config xml (doesn't work)
<bean id="myproperty" class="java.util.Optional">
<constructor-arg>
<value>com.MyObject</value>
</constructor-arg>
</bean>
<bean id="myfactory" class="com.Myfactory">
<property name="myproperty" ref="myproperty" />
</bean>
Does spring support generics beans?
The reason for using Optional is it provide some useful features such as checking value if null. You can complete checking and further action in one line of code.
getMyproperty().ifPresent(id -> call.setId(id));
Seems the problem have nothing to do with generics.
You simply need to properly tell Spring to create the bean using a factory method, as Optional can only be created though factory methods. Something like:
<bean id="myproperty" class="java.util.Optional" factory-method="of">
<constructor-arg type="java.lang.Object" value="com.MyObject" />
</bean>
for which it is supposed to mean creating the myproperty bean by Optional.of(com.MyObject.class) (Change the factory-method to ofNullable if that's the one you want to use)
Another option is to use SpEL (Spring Expression Language):
<bean id="mybean" ...>
<property name="optProp" value="#{ T(java.util.Optional).of( #wrapme) }"/>
</bean>
Where "wrapme" is the name of a bean defined elsewhere that you want to wrap in java.util.Optional.

Spring annotation component

I'm having some problems understanding how to use annotations, especially with beans.
I have one component
#Component
public class CommonJMSProducer
And I want to use it in another class and i thought I could do that to have a unique object
public class ArjelMessageSenderThread extends Thread {
#Inject
CommonJMSProducer commonJMSProducer;
but commonJMSProducer is null.
In my appContext.xml I have this :
<context:component-scan base-package="com.carnot.amm" />
Thanks
You have to configure Spring to use this autowiring feature:
<context:annotation-config/>
You can find the details of annotation-based config here.
ArjelMessageSenderThread also have to be managed by Spring otherwise it won't tamper with its members since it does not know about it.
OR
if you cannot make it a managed bean then you can do something like this:
ApplicationContext ctx = ...
ArjelMessageSenderThread someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
someBeanNotCreatedBySpring,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
OR
as others pointed out you can use annotations to use dependency injection on objects which are not created by Spring with the #Configurable annotation.
It depends on how you create instances of ArjelMessageSenderThread.
If ArjelMessageSenderThread is a bean that should be created by spring you just have to add #Component (and make sure the package is picked up by the component scan).
However, since you extend Thread, I don't think this should be a standard Spring bean. If you create instances of ArjelMessageSenderThread yourself by using new you should add the #Configurable annotation to ArjelMessageSenderThread. With #Configurable dependencies will be injected even if the instance is not created by Spring. See the documentation of #Configurable for more details and make sure you enabled load time weaving.
I used XML instead of annotations. This seemed difficult for not a big thing. Currently, I just have this more in the xml
<bean id="jmsFactoryCoffre" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<constructor-arg name="brokerURL" type="java.lang.String"
value="${brokerURL-coffre}" />
</bean>
<bean id="jmsTemplateCoffre" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref local="jmsFactoryCoffre" />
</property>
</bean>
<bean id="commonJMSProducer"
class="com.carnot.CommonJMSProducer">
<property name="jmsTemplate" ref="jmsTemplateCoffre" />
</bean>
And another class to get the bean
#Component
public class ApplicationContextUtils implements ApplicationContextAware {
Thanks anyway

Determine for which aggregation a bean is created

I have the following definition:
<bean id="logger" factory-method="createLog" scope="prototype" class="com.test.beans.LogBean" ></bean>
<bean id="aone" class="com.test.beans.AggregationOne">
<property name="log" ref="logger"></property>
</bean>
<bean id="atwo" class="com.test.beans.AggregationTwo">
<property name="log" ref="logger"></property>
</bean>
Is it possible to recognize for which object (aone or atwo) bean 'logger' is being created?
Why I'm asking: in a legacy application I have one log instance for all classes. I want to change level for some packages, but can't do that (except using filters, what I don't want). For that purpose I want to utilize some spring magic, if it exists for that case )
I don't think it can be done this way. What you could try is a BeanPostProcessor implementation which detects common logger object in beans and replaces it with a specific one.

Multiple Bean Instances in Spring

I was wondering if it is possible to specify x amount of the same bean in a list in Spring. For example, instead of having beans with ids: stage1, stage2,... stageN, as here:
<bean id="stage1" class="Stageclass"/>
<bean id="stage2" class="Stageclass"/>
<bean id="stages" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="stage1" />
<ref bean="stage2" />
</list>
</constructor-arg>
</bean>
Would it be possible to do something like the following?:
<bean id="stage1" class="Stageclass"/>
<bean id="stages" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="stage1" duplicate="20 times"/>
</list>
</constructor-arg>
</bean>
Thanks in advance.
If you use annotation based configuration and you specified list of objects with same interface as dependency for some class then spring will auto-wire aut-wire then for free. Example:
interface StageInterface {
//...
}
class StageImpl1 implements StageInterface {
//...
}
class StageImpl2 implements StageInterface {
//...
}
#Component
class StageContainer {
private final List<StageInterface> stages;
#Autowired
public StageContainer(List<StageInterface> stages) {
this.stages = stages;
}
public List<StageInterface> getStages() {
return stages;
}
}
This is a spring version 3+ feature.
I believe the same is possible with xml configuration as well. In your case that's probably will be the same class(StageClass), but with different configuration parameters.
Lookup method injection from http://static.springsource.org/spring/docs/2.5.x/reference/beans.html solved the problem. Just needed to make sure the bean I wanted multiple instances of had scope="prototype"
You can't do that using standard Spring's default namespace. However you can implement your own custom namespace where you could support such syntax.
Alternatively, you can implement a static method that would create an ArrayList instance with duplicated elements.

Does spring mvc have the concept of before/after controller action events?

Does spring mvc have the concept of events firing before/after a controller action?
I am currently using a filter, but I could also inherit from a basecontroller for specific sections of my website and use before/after events if they exist.
So I mean I can create an event that fires just before a controller's action fires, or an event that fires after.
I think you are looking for interceptors. I don't know what strategy you are using for routing you requests to your controller methods, so I assume you are using annotations. Then, here is how you could put your interceptor on the stack:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="loginInterceptor"/>
</list>
</property>
</bean
Where loginInterceptor is the id of a bean declared in your application context which implements the interface org.springframework.validation.Validator
This looks like something you can achieve using Spring AOP.

Categories