spring enable aspectj-autoproxy only for some aspect beans - spring

I'm writing a plugin for an existing application and I need to add an "After returning" advice to the certain method. aspectj-autoproxy is currently disabled.
To avoid possible side effects for existing classes that have AspectJ annotations that are currently ignored I'd like to enable these annotations handling only for my bean. However, #EnableAspectJAutoProxy affects the entire context.
The only thing that comes to my mind is to manually construct the proxy using ProxyFactory, but after this I'll have two beans and I won't be able to use AspectJ expressions.
#Configuration
public class MyConf {
#Primary
#Bean
public SomeBean getSomeBean(#Autowired #Qualifier("SomeBeanImpl") target) {
ProxyFactory factory = new ProxyFactory(target);
// setup the advice, the method filter etc.
return (SomeBean)factory.getProxy();
}
Is there some other set of annotations to create advices without globally enabling aspectj-autoproxy?
Upd
Looks like I need to dig towards manually registering another AnnotationAwareAspectJAutoProxyCreator instance with includePatterns property set.

Both #EnableAspectJAutoProxy and <aop:aspectj-autoproxy> enable creation of the bean post-processor singleton AnnotationAwareAspectJAutoProxyCreator. This object has an optional property includePatterns for filtering the eligible annotated aspect beans. By default all annotated aspect beans are eligible which means that advisors will be created for their annotated methods and these advisors will later be matched while wrapping the other beans with proxies.
includePatterns is only configurable via the XML tag <aop:include> , there's no annotation equivalent. If you have <aop:include> in one of your XML configs you can't clear includePatterns to make all annotated aspects eligible.
All this makes it pointless to use AspectJ annotations if you want to avoid side effects. To create just one aspect bean without enabling aspectj-autoproxy it's optimal to configure that bean with the <aop:config> tag:
<aop:config>
<aop:aspect ref="aroundExample">
<aop:after-returning method="afterDoSomething"
pointcut="execution(* org.foo.Some.doSomething(..)) && target(target) && args(param,..)"
returning="retval"
arg-names="target,retval,param"
/>
</aop:aspect>
</aop:config>
<!--
This is disabled:
<aop:aspectj-autoproxy>
<aop:include name="aroundExample"></aop:include>
</aop:aspectj-autoproxy>
-->
The annotations on the aspect bean are no longer needed:
#Component
// #Aspect
// #EnableAspectJAutoProxy -- yes, it wasn't necessary to place it on a #Configuration bean
#ImportResource("classpath:org/foo/aroundexample-config.xml")
public class AroundExample {
// #AfterReturning(pointcut = "execution(* " + "org.foo.Some.doSomething"
// + "(..)) && target(target) && args(param,..)", returning = "retval",
// argNames = "target,retval,param")
public void afterDoSomething(
// JoinPoint jp,
Some target, String retval, String param) throws Throwable {
// jp.getThis();
System.err.println("afterDoSomething: " + param + " " + retval);
}
}

Related

Bean overriding in Spring context that uses both annotation and xml config

There is a spring project A which is completely annotation based.
I need to override some beans conditionally in project B which is a legacy application using Spring 4.1.3 and uses xml based config.
There is FooConfig which is configuring beans using #ComponentScan. This config is a third party code for me. i.e I do not have access for this
#ComponentScan(basePackages = {"com.foo.bean"})
#Configuration
public class FooConfig {
}
I have created a BarConfig at my end, which imports this FooConfig and overrides some beans based on a condition. This is achieved using #Conditional
#Configuration
#Import(FooConfig.class)
public class BarConfig {
#Bean(name="helloService")
#Conditional(IsSpanishCondition.class)
public HelloService getHelloService() {
return new HelloService() {
#Override
public String getGreeting(String name) {
return "Hola "+name;
}
};
}
}
And I have included BarConfig in my application-context.xml
<context:annotation-config/>
<bean class="com.foo.config.BarConfig"/>
While this approach works flawlessly in Spring 5.1.2.RELEASE, it does not work in Spring 4.1.3.RELEASE
00:14:20.617 [main] INFO org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader - Skipping bean definition for [BeanMethod:name=getHelloService,declaringClass=com.foo.config.BarConfig]: a definition for bean 'helloService' already exists. This top-level bean definition is considered as an override.
Also, I have observed the same issue in Spring 4 in a completely annotation based context as well. i.e. it is not because of xml and annotation config mix but due to the Spring versions used here
Questions
What changed in Spring 5?
Is there any rule of thumb while working with a Spring application that uses both xml and annotation config especially when it comes to overriding the beans?
Also FTR, these are the solutions that worked
1.Overriding the beans using BeanPostProcessor
2.Using profiles. But this wouldn't work for complicated conditions.
#Profile("ENGLISH")
#Configuration
#Import(FooConfig.class)
public class EnglishConfig {
}
#Profile("SPANISH")
#Configuration
public class SpanishConfig {
#Bean(name="helloService")
public HelloService getHelloService() {
return new HelloService() {
#Override
public String getGreeting(String name) {
return "Hola "+name;
}
};
}
}
The issue here is that you are trying to override a xml bean from a #Configuration class, now I'm not 100% sure, but in spring 4 a xml bean still had precedence in choosing a bean, so the #Configuration beans would not get permission to overwrite the xml bean. Which was resolved in spring 5.
Your approach to use BeanPostProcessor is i guess the only viable solution for this.
I'm thinking maybe you could use a different bean name, implement your own behaviour and use #Qualifier annotation to choose which bean will get selected?

No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] while deploying service into PCF [duplicate]

Please explain the following about NoSuchBeanDefinitionException exception in Spring:
What does it mean?
Under what conditions will it be thrown?
How can I prevent it?
This post is designed to be a comprehensive Q&A about occurrences of NoSuchBeanDefinitionException in applications using Spring.
The javadoc of NoSuchBeanDefinitionException explains
Exception thrown when a BeanFactory is asked for a bean instance for
which it cannot find a definition. This may point to a non-existing
bean, a non-unique bean, or a manually registered singleton instance
without an associated bean definition.
A BeanFactory is basically the abstraction representing Spring's Inversion of Control container. It exposes beans internally and externally, to your application. When it cannot find or retrieve these beans, it throws a NoSuchBeanDefinitionException.
Below are simple reasons why a BeanFactory (or related classes) would not be able to find a bean and how you can make sure it does.
The bean doesn't exist, it wasn't registered
In the example below
#Configuration
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
ctx.getBean(Foo.class);
}
}
class Foo {}
we haven't registered a bean definition for the type Foo either through a #Bean method, #Component scanning, an XML definition, or any other way. The BeanFactory managed by the AnnotationConfigApplicationContext therefore has no indication of where to get the bean requested by getBean(Foo.class). The snippet above throws
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.Foo] is defined
Similarly, the exception could have been thrown while trying to satisfy an #Autowired dependency. For example,
#Configuration
#ComponentScan
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
}
}
#Component
class Foo { #Autowired Bar bar; }
class Bar { }
Here, a bean definition is registered for Foo through #ComponentScan. But Spring knows nothing of Bar. It therefore fails to find a corresponding bean while trying to autowire the bar field of the Foo bean instance. It throws (nested inside a UnsatisfiedDependencyException)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.Bar] found for dependency [com.example.Bar]:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
There are multiple ways to register bean definitions.
#Bean method in a #Configuration class or <bean> in XML configuration
#Component (and its meta-annotations, eg. #Repository) through #ComponentScan or <context:component-scan ... /> in XML
Manually through GenericApplicationContext#registerBeanDefinition
Manually through BeanDefinitionRegistryPostProcessor
...and more.
Make sure the beans you expect are properly registered.
A common error is to register beans multiple times, ie. mixing the options above for the same type. For example, I might have
#Component
public class Foo {}
and an XML configuration with
<context:component-scan base-packages="com.example" />
<bean name="eg-different-name" class="com.example.Foo />
Such a configuration would register two beans of type Foo, one with name foo and another with name eg-different-name. Make sure you're not accidentally registering more beans than you wanted. Which leads us to...
If you're using both XML and annotation-based configurations, make sure you import one from the other. XML provides
<import resource=""/>
while Java provides the #ImportResource annotation.
Expected single matching bean, but found 2 (or more)
There are times when you need multiple beans for the same type (or interface). For example, your application may use two databases, a MySQL instance and an Oracle one. In such a case, you'd have two DataSource beans to manage connections to each one. For (simplified) example, the following
#Configuration
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
System.out.println(ctx.getBean(DataSource.class));
}
#Bean(name = "mysql")
public DataSource mysql() { return new MySQL(); }
#Bean(name = "oracle")
public DataSource oracle() { return new Oracle(); }
}
interface DataSource{}
class MySQL implements DataSource {}
class Oracle implements DataSource {}
throws
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.example.DataSource] is defined:
expected single matching bean but found 2: oracle,mysql
because both beans registered through #Bean methods satisfied the requirement of BeanFactory#getBean(Class), ie. they both implement DataSource. In this example, Spring has no mechanism to differentiate or prioritize between the two. But such mechanisms exists.
You could use #Primary (and its equivalent in XML) as described in the documentation and in this post. With this change
#Bean(name = "mysql")
#Primary
public DataSource mysql() { return new MySQL(); }
the previous snippet would not throw the exception and would instead return the mysql bean.
You can also use #Qualifier (and its equivalent in XML) to have more control over the bean selection process, as described in the documentation. While #Autowired is primarily used to autowire by type, #Qualifier lets you autowire by name. For example,
#Bean(name = "mysql")
#Qualifier(value = "main")
public DataSource mysql() { return new MySQL(); }
could now be injected as
#Qualifier("main") // or #Qualifier("mysql"), to use the bean name
private DataSource dataSource;
without issue. #Resource is also an option.
Using wrong bean name
Just as there are multiple ways to register beans, there are also multiple ways to name them.
#Bean has name
The name of this bean, or if plural, aliases for this bean. If left
unspecified the name of the bean is the name of the annotated method.
If specified, the method name is ignored.
<bean> has the id attribute to represent the unique identifier for a bean and name can be used to create one or more aliases illegal in an (XML) id.
#Component and its meta annotations have value
The value may indicate a suggestion for a logical component name, to
be turned into a Spring bean in case of an autodetected component.
If that's left unspecified, a bean name is automatically generated for the annotated type, typically the lower camel case version of the type name. For example MyClassName becomes myClassName as its bean name. Bean names are case sensitive. Also note that wrong names/capitalization typically occur in beans referred to by string like #DependsOn("my BeanName") or XML config files.
#Qualifier, as mentioned earlier, lets you add more aliases to a bean.
Make sure you use the right name when referring to a bean.
More advanced cases
Profiles
Bean definition profiles allow you to register beans conditionally. #Profile, specifically,
Indicates that a component is eligible for registration when one or
more specified profiles are active.
A profile is a named logical grouping that may be activated
programmatically via
ConfigurableEnvironment.setActiveProfiles(java.lang.String...) or
declaratively by setting the spring.profiles.active property as a JVM
system property, as an environment variable, or as a Servlet context
parameter in web.xml for web applications. Profiles may also be
activated declaratively in integration tests via the #ActiveProfiles
annotation.
Consider this examples where the spring.profiles.active property is not set.
#Configuration
#ComponentScan
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
System.out.println(Arrays.toString(ctx.getEnvironment().getActiveProfiles()));
System.out.println(ctx.getBean(Foo.class));
}
}
#Profile(value = "StackOverflow")
#Component
class Foo {
}
This will show no active profiles and throw a NoSuchBeanDefinitionException for a Foo bean. Since the StackOverflow profile wasn't active, the bean wasn't registered.
Instead, if I initialize the ApplicationContext while registering the appropriate profile
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("StackOverflow");
ctx.register(Example.class);
ctx.refresh();
the bean is registered and can be returned/injected.
AOP Proxies
Spring uses AOP proxies a lot to implement advanced behavior. Some examples include:
Transaction management with #Transactional
Caching with #Cacheable
Scheduling and asynchronous execution with #Async and #Scheduled
To achieve this, Spring has two options:
Use the JDK's Proxy class to create an instance of a dynamic class at runtime which only implements your bean's interfaces and delegates all method invocations to an actual bean instance.
Use CGLIB proxies to create an instance of a dynamic class at runtime which implements both interfaces and concrete types of your target bean and delegates all method invocations to an actual bean instance.
Take this example of JDK proxies (achieved through #EnableAsync's default proxyTargetClass of false)
#Configuration
#EnableAsync
public class Example {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
System.out.println(ctx.getBean(HttpClientImpl.class).getClass());
}
}
interface HttpClient {
void doGetAsync();
}
#Component
class HttpClientImpl implements HttpClient {
#Async
public void doGetAsync() {
System.out.println(Thread.currentThread());
}
}
Here, Spring attempts to find a bean of type HttpClientImpl which we expect to find because the type is clearly annotated with #Component. However, instead, we get an exception
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.example.HttpClientImpl] is defined
Spring wrapped the HttpClientImpl bean and exposed it through a Proxy object that only implements HttpClient. So you could retrieve it with
ctx.getBean(HttpClient.class) // returns a dynamic class: com.example.$Proxy33
// or
#Autowired private HttpClient httpClient;
It's always recommended to program to interfaces. When you can't, you can tell Spring to use CGLIB proxies. For example, with #EnableAsync, you can set proxyTargetClass to true. Similar annotations (EnableTransactionManagement, etc.) have similar attributes. XML will also have equivalent configuration options.
ApplicationContext Hierarchies - Spring MVC
Spring lets you build ApplicationContext instances with other ApplicationContext instances as parents, using ConfigurableApplicationContext#setParent(ApplicationContext). A child context will have access to beans in the parent context, but the opposite is not true. This post goes into detail about when this is useful, particularly in Spring MVC.
In a typical Spring MVC application, you define two contexts: one for the entire application (the root) and one specifically for the DispatcherServlet (routing, handler methods, controllers). You can get more details here:
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
It's also very well explained in the official documentation, here.
A common error in Spring MVC configurations is to declare the WebMVC configuration in the root context with #EnableWebMvc annotated #Configuration classes or <mvc:annotation-driven /> in XML, but the #Controller beans in the servlet context. Since the root context cannot reach into the servlet context to find any beans, no handlers are registered and all requests fail with 404s. You won't see a NoSuchBeanDefinitionException, but the effect is the same.
Make sure your beans are registered in the appropriate context, ie. where they can be found by the beans registered for WebMVC (HandlerMapping, HandlerAdapter, ViewResolver, ExceptionResolver, etc.). The best solution is to properly isolate beans. The DispatcherServlet is responsible for routing and handling requests so all related beans should go into its context. The ContextLoaderListener, which loads the root context, should initialize any beans the rest of your application needs: services, repositories, etc.
Arrays, collections, and maps
Beans of some known types are handled in special ways by Spring. For example, if you tried to inject an array of MovieCatalog into a field
#Autowired
private MovieCatalog[] movieCatalogs;
Spring will find all beans of type MovieCatalog, wrap them in an array, and inject that array. This is described in the Spring documentation discussing #Autowired. Similar behavior applies to Set, List, and Collection injection targets.
For a Map injection target, Spring will also behave this way if the key type is String. For example, if you have
#Autowired
private Map<String, MovieCatalog> movies;
Spring will find all beans of type MovieCatalog and add them as values to a Map, where the corresponding key will be their bean name.
As described previously, if no beans of the requested type are available, Spring will throw a NoSuchBeanDefinitionException. Sometimes, however, you just want to declare a bean of these collection types like
#Bean
public List<Foo> fooList() {
return Arrays.asList(new Foo());
}
and inject them
#Autowired
private List<Foo> foos;
In this example, Spring would fail with a NoSuchBeanDefinitionException because there are no Foo beans in your context. But you didn't want a Foo bean, you wanted a List<Foo> bean. Before Spring 4.3, you'd have to use #Resource
For beans that are themselves defined as a collection/map or array
type, #Resource is a fine solution, referring to the specific
collection or array bean by unique name. That said, as of 4.3,
collection/map and array types can be matched through Spring’s
#Autowired type matching algorithm as well, as long as the element
type information is preserved in #Bean return type signatures or
collection inheritance hierarchies. In this case, qualifier values can
be used to select among same-typed collections, as outlined in the
previous paragraph.
This works for constructor, setter, and field injection.
#Resource
private List<Foo> foos;
// or since 4.3
public Example(#Autowired List<Foo> foos) {}
However, it will fail for #Bean methods, ie.
#Bean
public Bar other(List<Foo> foos) {
new Bar(foos);
}
Here, Spring ignores any #Resource or #Autowired annotating the method, because it's a #Bean method, and therefore can't apply the behavior described in the documentation. However, you can use Spring Expression Language (SpEL) to refer to beans by their name. In the example above, you could use
#Bean
public Bar other(#Value("#{fooList}") List<Foo> foos) {
new Bar(foos);
}
to refer to the bean named fooList and inject that.

How to do conditional auto-wiring in Spring?

Has anyone tried to auto-wire different beans into a Spring-managed bean based on a condition? For e.g. if some condition is met, inject class A, else B? I saw in one of the Google search results that it is possible with SpEL (Spring Expression Language), but could not locate a working example.
There are multiple ways to achieve this. Mostly this depends on the conditioning you want to perform.
Factory bean
You can implement simple factory bean to do the conditional wiring. Such factory bean can contain complex conditioning logic:
public MyBeanFactoryBean implements FactoryBean<MyBean> {
// Using app context instead of bean references so that the unused
// dependency can be left uninitialized if it is lazily initialized
#Autowired
private ApplicationContext applicationContext;
public MyBean getObject() {
MyBean myBean = new MyBean();
if (true /* some condition */) {
myBean.setDependency(applicationContext.getBean(DependencyX.class));
} else {
myBean.setDependency(applicationContext.getBean(DependencyY.class));
}
return myBean;
}
// Implementation of isSingleton => false and getObjectType
}
Maybe a bit better approach is if you use factory bean to create the dependency bean in case you want to have only one such bean in your application context:
public MyDependencyFactoryBean implements FactoryBean<MyDependency> {
public MyDependency getObject() {
if (true /* some condition */) {
return new MyDependencyX();
} else {
return new MyDependencyY();
}
}
// Implementation of isSingleton => false and getObjectType
}
SpEL
With SpEL there are many possibilities. Most common are system property based conditions:
<bean class="com.example.MyBean">
<property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
</bean>
Property placeholder
You can have property placeholder resolve your bean reference. The dependency name can be part of the application configuration.
<bean class="com.example.MyBean">
<property name="dependency" ref="${dependencyName}" />
</bean>
Spring profiles
Usually the condition you want to evaluate means that a whole set of beans should or should not be registered. Spring profiles can be used for this:
<!-- Default dependency which is referred by myBean -->
<bean id="dependency" class="com.example.DependencyX" />
<beans profile="myProfile">
<!-- Override `dependency` definition if myProfile is active -->
<bean id="dependency" class="com.example.DependencyY" />
</beans>
Other methods can mark the bean definition as lazy-init="true", but the definition will be still registered inside application context (and making your life harder when using unqualified autowiring). You can also use profiles with #Component based beans via #Profile annotation.
Check ApplicationContextInitialier (or this example) to see how you can activate profiles programatically (i.e. based on your condition).
Java config
This is why Java based config is being so popular as you can do:
#Bean
public MyBean myBean() {
MyBean myBean = new MyBean();
if (true /* some condition */) {
myBean.setDependency(dependencyX());
} else {
myBean.setDependency(dependencyY());
}
return myBean;
}
Of course you can use more or less all configuration methods in the java based config as well (via #Profile, #Value or #Qualifier + #Autowired).
Post processor
Spring offers numerous hook points and SPIs, where you can participate in the application context life-cycle. This section requires a bit more knowledge of Spring's inner workings.
BeanFactoryPostProcessors can read and alter bean definitions (e.g. property placeholder ${} resolution is implemented this way).
BeanPostProcessors can process bean instances. It is possible to check freshly created bean and play with it (e.g. #Scheduled annotation processing is implemented this way).
MergedBeanDefinitionPostProcessor is extension of bean post processor and can alter the bean definition just before it is being instantiated (#Autowired annotation processing is implemented this way).
UPDATE Oct 2015
Spring 4 has added a new method how to do conditional bean registration via #Conditional annotation. That is worth checking as well.
Of course there are numerous other ways with Spring Boot alone via its #ConditionalOn*.
Also note that both #Import and #ComponentScan (and their XML counterparts) undergo property resolution (i.e. you can use ${}).
I had a case where I needed to inject different beans depending on property: "my.property". In my case this solution was successful:
<property name="name" ref="#{ ${my.property:false}==true ? 'bean1' : 'bean2' }"/>
I needed to add the apostrophes around bean names in order to make it work.
In your #Configuration class declare a bean to be conditionally created:
#Bean
#Conditional(CustomFeatureCondition.class)
public Stuff stuff() {
return new Stuff ();
}
In the place of using just #Autowire it with required = false option:
#Component
#Setter(onMethod_ = #Autowired(required = false))
public class AnotherStuff {
private Stuff stuff;
// do stuff here
}
This way you'll get Stuff bean if it exists in the context and stuff = null if it doesn't.
I suppose the simpest way:
#Autowired #Lazy
protected A a;
#Autowired #Lazy
protected B b;
void do(){
if(...) { // any condition
// use a
} else {
// use b
}
}
In case you do not declare nessassary bean, Spring throws at runtime NoSuchBeanDefinitionException

How do I prevent Spring from instantiating a prototype scoped bean on context refresh?

I am using prototype scoped bean definitions in my Spring XML descriptors to configure the default properties (these beans have many properties) and then I call the application context with a getBean(beanName, ctorArgs[]) to create instances.
The bean definitions require 2-3 constructor arguments that supply logically unique keys used for things like key properties for the JMX ObjectName etc. Additionally, the variables that the constructor arguments are written to are final.
What I am seeing is that when the application context refreshes, it attempts to instantiate these prototypes, which seems completely the opposite of what you want prototypes to do. They're templates, not actual instances. To work around this, I have been configuring the prototypes with bogus ctor values so these bogus bean instances are instantiated and I simply filter out the created MBeans later in the code.
My question is, how do I configure the application context to register these prototype bean definitions, but not instantiate them until I make a getBean call ?
UPDATE:
The problem is a bit more complicated than I initialy thought. In fact, lazy is the default behaviour for prototype-scoped beans. I digged a bit and I managed to reproduce your problem and find the solution. So what is the problem?
You probably have <aop:scoped-proxy/> enabled or (#ComponentScan(scopedProxy=...) equivalent). During context refresh Spring wraps your prototype bean (ClosedMetricSubscriberFeed) with scoped proxy. It uses class proxy because (a) class proxies are chosen or (b) the class has no interfaces.
The class-based proxy is basically a CGLIB subclass of your bean that must call (due to JVM rules) a base class's constructor. And CGLIB generated class always calls no-arg constructor.
I know this sounds complicated, here's what you can do:
Disable <aop:scoped-proxy/>. Just like that.
Provide a dummy no-arg constructor and deprecate it just in case. Unfortunately you will have to discover such bogus instances manunally. Note that in this case the class will be of type: ``.
Extract an interface from your class and use interfaces for scoped proxies:
.
#Scope(
value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.INTERFACES)
Old answer:
Use lazy initialization with #Lazy annotation or lazy-init="true" (see 4.4.4 Lazy-initialized beans in reference documentation) configuration attribute.
<bean id="proto" class="MyPrototype" scope="prototype" lazy-init="true"/>
or:
#Service
#Scope("prototype")
#Lazy
public class MyPrototype {/*...*/}
I use a private, deprecated, no-arg constructor that throws an IllegalStateException. The context loads fine, getBean() with the constructor args works fine, and getBean() without args throws the exception.
package a;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component("myCommand")
#Scope("prototype")
public class Command {
final protected String name;
#Deprecated
private Command() {throw new IllegalStateException("Only for Spring"); }
public Command(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return "Command [name=" + name + "]";
}
}

Use Spring #Transactional in Scala

We have a mixed Java and Scala project, which uses Spring transaction management. We are using the Spring aspects to weave the files with #Transactional annotated methods.
The problem is, that the Scala classes aren't woven with the Spring transaction aspects. How can I configure Spring to regard the transaction in Scala?
Spring needs your transaction boundary to begin with Spring-managed beans, so this precludes #Transactional Scala classes.
It sounds like the simple solution is to make service facades which are #Transactional Java classes instantiated as Spring beans. These can delegate to your Scala service/core code.
A Scala-only solution is to use Eberhard Wolff's closure that creates a manual transaction. Usage:
transactional() {
// do stuff in transaction
}
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionManagement.scala
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionAttributeWithRollbackRules.scala
Found here: http://www.slideshare.net/ewolff/scala-and-spring (slide 41)
License: Apache
There is nothing special about Spring's #Transactional support in Scala and you can use it without any Java code. Just make sure that you have "pure" traits for beans, which implementations would use #Transactional annotation. You should also declare a bean with PlatformTransactionManager type (if you are using .xml-based Spring configuration, you should use "transactionManager" for bean name, see EnableTransactionManagement's JavaDoc for details). Also, if you are using annotation-based configuration classes, be sure that these classes are placed in their own dedicated files, i.e. don't place any other classes (companion object is OK) in the same file. Here is simple working example:
SomeService.scala:
trait SomeService {
def someMethod()
}
// it is safe to place impl in the same file, but still avoid doing it
class SomeServiceImpl extends SomeService {
#Transactional
def someMethod() {
// method body will be executed in transactional context
}
}
AppConfiguration.scala:
#Configuration
#EnableTransactionManagement
class AppConfiguration {
#Bean
def transactionManager(): PlatformTransactionManager = {
// bean with PlatformTransactionManager type is required
}
#Bean
def someService(): SomeService = {
// someService bean will be proxied with transaction support
new SomeServiceImpl
}
}
// companion object is OK here
object AppConfiguration {
// maybe some helper methods
}
// but DO NOT place any other trait/class/object in this file, otherwise Spring will behave incorrectly!

Resources