I want to convert some of our internal API into a spring bean spring interceptor that we can use in other projects. This API needs some instantiation and other logic which I want to encapsulate in this bean so that we can just put the bean into our app context with necessary propoerties alone, and this will then apply the logic.
I remember having read an article on this somewhere in the past - but cant find it now.
Any pointers to something similar will be helpful
EDIT: Sorry, I meant a spring interceptor, not a bean - my bad - please see my edit. I want to apply this interceptor to another bean dealing in XML messages.
EDIT 2: ANSWER FOUND
found it!
I found the answer to this - we were looking to insert the interceptor at the point where we were calling our webservice. So I looked at the interceptor package in spring-ws and found this end point interceptor interface. We will now implement this interceptor and put our processing logic in the appropriate handle*() method.
http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/server/EndpointInterceptor.html
As with everything in spring, there are a million ways to implement AOP. Check out the spring doco on AOP, the section on declaring aspects in xml may be the most convenient in your situation. You can configure an aspect
<aop:aspect id="myAspect" ref="existingBean">
<aop:before pointcut="execution(* com.package.to.intercept.*(..))" method="existingMethod"/>
</aop:aspect>
Or you could create new classes that use the AspectJ annotations and use those aspects to farm off to your actual work to your existing beans.
Found it!
See this link - http://static.springsource.org/spring-flex/docs/1.0.x/reference/html/ch02s09.html
This gives the interface that you need to implement and the XML definition.
Found a more suitable answer - see the edit in main question.
Related
Assume I have Spring MVC powered application with Spring security. I have:
UserBean class which provides CRUD operations on table User
UserController : controller which expose operation on User to http clients
UserLogin: Authentication provider from Spring security, which authenticates users.
How should I configure my application if:
I want simple XML configuration, with auto-discovering beans by annotations (<context:component-scan base-package="org.example"/>)
UserLogin and UserController needs UserBean to work
UserLogin and UserController use transaction annotations and aspect annotations
I see the following oportunities:
Create one common Spring XML configuration file, used both by DispatcherServlet and ContextLoaderListener
Disadvantage: nobody shows that solution in tutorial. All beans are duplicated (one instance in ContextLoaderListener context, second in DispatcherServlet). Duplication may cause some hard to track bugs. Duplication is not elegant
Create two Spring XML configuration files, one for ContextLoaderListener (main) and one for DispatcherServlet (controllers). UserBean is declared in first config and visible in second one
Disadvantage: to avoid duplication I have to add complex component scanning rules to both files (context:component-scan). <tx:annotation-driven and <aop:aspectj-autoproxy/> must be defined in both files. I will have still doubts which config file is appropiate when declaring new stuff.
Create two Spring XML configuration files and include third for common settings like <tx:annotation-driven
Disadvantage: I wanted simple solution...
Summary: I'm looking for good practice to configure application with Spring MVC + Spring Security AND security part is highly connected with business part. I was searching for good example but I always find case when security code is isolated from business code. But I need example when security and business share the code
Similar question: ContextLoaderListener or not?
I have two xml files for my configuration, no particular reason, that's just how it worked out.
These sample spring security projects provide good examples of lots of different types of configurations maybe you can find something that works for you:
https://github.com/spring-projects/spring-security/tree/master/samples
Hidden message in my question was: having two contexts is stupid.
Did someone already notice that?
Is there a way to have single application configuration?
Answers:
Yes. https://jira.springsource.org/browse/SPR-6903
Yes. https://github.com/michaldo/spring-single-context-demo
The best practice which applies to my case is described here: https://stackoverflow.com/a/14032213/2365727
Definitely need some expert help with this! I think this is mainly a Spring Security question, but as I don't know for sure, so I am also tagging with the general Spring tag!
When the Application Context is loaded (mine is all via Java Config, though I don't believe that matters), the "DefaultListableBeanFactory" is processed and eventually (via the ProxyFactory) Spring Security Advisors are added. This is great when I have Spring Beans as I have Permissions that need authorization.
My question is: how do I get the same effect when I no longer require those classes to be Spring Beans? Said differently, if I have an object instance created as a singleton bean via Java Config and the authorization is working correctly, is it possible to maintain that with the object instance being a POJO? Again, for the experts, I want the interception chain returned in the JdkDynamicAopProxy to contain the Spring Security interceptors.
And "no", I am not really expecting an answer to this, maybe just hoping!!!
To add security interceptors to beans not instantiated by spring container
switch global-security tag to mode aspectj and weave the provided AnnotationSecurityAspect in the aspecj module.
For your second question I suppose that you want to do one of the following:
Use a ProxyFactoryBean to secure a bean.
Create security proxies programmatically: Use ProxyFactory.addAdvice() method.
Add the security interceptor to all proxies created by an AutoProxyCreator: This usually don't needed, but you can use the AbstractAutoProxyCreator.interceptorNames property to add common interceptors. The global-security tag parser uses a generated name for the MethodSecurityInterceptor, so you need to configure the interceptor manually and set a consistent SecurityMetadataSource.
I have 20 beans in my application-context,I want to load a particular bean after all the beans are loaded. Is there a way for this?
You can use depends-on to force bean initialization order.
For example if bean1 depends on bean2 and bean3, you can put:
<bean id="bean1" class="YourBean" depends-on="bean2,bean3">
in your spring context.
As #skaffman said, this is a very strange requirement. Depending on your needs there are better solutions:
If you just need to start a process when Spring context is initialized, don't use a #PostConstruct annotated method (or an InitializingBean). ApplicationListener is probably what you need.
If you are worried because you need some beans injected in a #PostConstruct annotated method don't bother: Spring is usually smart enough for resolving such dependencies. If it isn't in your case, maybe you have an overcomplicated bean design.
If this isn't enough, you can follow #soulcheck instructions. This answer can probably help you in order to get cleaner configuration files.
If this don't help you, please give us some more information on what are you trying to achieve.
Can anyone explain what I need to do to implement my own annotation that would add functionality to my web requests?
For example:
#Controller
public class MyController {
#RequestMapping("/abc")
#RequiresSomeSpecialHandling
public void handleSecureRequest() {
}
}
Here #RequiresSomeSpecialHandling would be my own annotation that causes some special work to be done before or after the given web request /abc.
I know that on a very high level I would need to write a bean post processor, scan classes for my annotations, and inject custom mvc interceptors when needed. But are there any shortcuts to simplify this task? Especially for the two examples above.
Thanks in advance,
This kind of Annotations, (that add additional functionality when invoking a method) looks like annotations that trigger an AOP Advice.
#see Spring Reference Chapter 7. Aspect Oriented Programming with Spring
The idea is to use the Annotation to trigger the AOP Advice.
like:
#Pointcut("#target(com.example.RequiresAuth)")
Depends on what you want to do as a result of #RequiresSomeSpecialHandling. E.g. do you want it to influence request mappings or the invocation of the method (i.e. resolving method arguments, processing the return value)?
The support for annotated classes in Spring 3.1 became much more customizable. You can browse some examples in this repo.
Also keep in mind that a HandlerInterceptor in Spring 3.1 can cast the handler Object to HandlerMethod, which gives you access to the exact method including its annotations. That may be enough for what you need to do.
If caching is one of your goals, take a look at the #Cacheable annotation (and its siblings #CachePut, #CacheEvict and #Caching), available as of Spring 3.1.
Wicket has this device called a lazy proxy factory. Given:
<property name="foo" ref="beanx"/>
the idea is to auto-generate a proxy in place of 'beanx', and then only initialize beanx if and when something actually calls a method on it.
It seems as if this might be a core Spring capability. Is it there somewhere?
See LazyInitTargetSource; that might do what you want. It requires use of lazy-init="true" on the target bean as well, though.
Spring singleton beans, the closest thing to what you want, are created when the spring context is initialized: http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes. So I believe the short answer is "no." You can implement your own scope to do this by extending the Spring classes quite easily, though.
Spring session/request scope is implemented using the technique you describe, but it is only intended to handle transitions between scope cardinalities, not instance creation. So spring uses the same concepts, but you'd probably have to create your own implementation.