Annotation-Driven Dependency Injection in Spring 2.1

Spring 2.0 introduced annotation support and annotation-aware configuration options that can be leveraged by Spring users who are developing with Java 5 (or later versions):
| @Transactional | for demarcating and configuring transaction definitions |
|---|---|
| @Aspect (AspectJ) | for defining aspects along with @Pointcut definitions and advice (@Before, @After, @Around) |
| @Repository | for indicating a class that is operating as a repository (a.k.a. Data Access Object or DAO) |
| @Required | for enforcing annotated bean properties are provided a value |
With Spring 2.1, this theme of annotation-driven configuration has been significantly extended and will continue to evolve as we progress toward the RC1 release. In fact, it is now possible to drive Spring's dependency injection via annotations. Furthermore, Spring can discover beans that need to be configured within an application context.
This blog entry will serve as a tutorial-style introduction to the basic features in 10 easy-to-follow steps. I will follow up later in the week with information on some more advanced features and customization options. If you are interested in alternative configuration options, you should also check out the Spring Java Configuration project and this blog.
This tutorial requires at least Java 5, and Java 6 is recommended (otherwise there is a single requirement at the end of step 1).
Step 1:
Grab spring-framework-2.1-m1-with-dependencies.zip. After extracting the archive, you will find the spring.jar and spring-mock.jar in the 'dist' directory. Add them to your CLASSPATH as well as the following (paths shown are relative to the 'lib' directory of the extracted 2.1-m1 archive):
- asm/asm-2.2.3.jar
- asm/asm-commons-2.2.3.jar
- aspectj/aspectjweaver.jar
- hsqldb/hsqldb.jar
- jakarta-commons/commons-logging.jar
- log4j/log4j-1.2.14.jar
(NOTE: If you are not running on Java 6, you will also need to add j2ee/common-annotations.jar)
Step 2:
Provide the interfaces and classes for the example. I have tried to keep it as simple as possible yet capable of demonstrating the main functionality. I am including all of the code and configuration in a single "blog" package. I would encourage following that same guideline so that the examples work as-is; otherwise, be sure to make the necessary modifications. First, the GreetingService interface:
Then, a simple implementation:
private MessageRepository messageRepository;
public void setMessageRepository(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
public String greet(String name) {
Locale locale = Locale.getDefault();
String message = messageRepository.getMessage(locale.getDisplayLanguage());
return message + " " + name;
}
}
Since the service depends upon a MessageRepository, define that interface next:
And for now, a stub implementation:
Map<String,String> messages = new HashMap<String,String>();
public void initialize() {
messages.put("English", "Welcome");
messages.put("Deutsch", "Willkommen");
}
public String getMessage(String language) {
return messages.get(language);
}
}
Step 3:
Define the beans for a Spring application context. Notice, that I am including a new 'context' namespace (NOTE: the 'aop' namespace is also included here and will be used in the final step):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.1.xsd">
<bean class="blog.GreetingServiceImpl"/>
<bean class="blog.StubMessageRepository"/>
</beans>
Obviously this configuration looks a little sparse. As you can probably guess, the 'context' namespace will soon play a role.
Step 4:
Provide a simple test case leveraging Spring's base support class:
private GreetingService greetingService;
public void setGreetingService(GreetingService greetingService) {
this.greetingService = greetingService;
}
@Override
protected String[] getConfigLocations() {
return new String[] { "/blog/applicationContext.xml" };
}
public void testEnglishWelcome() {
Locale.setDefault(Locale.ENGLISH);
String name = "Spring Community";
String greeting = greetingService.greet(name);
assertEquals("Welcome " + name, greeting);
}
public void testGermanWelcome() {
Locale.setDefault(Locale.GERMAN);
String name = "Spring Community";
String greeting = greetingService.greet(name);
assertEquals("Willkommen " + name, greeting);
}
}
Try running the tests and notice that they fail with a NullPointerException. This is to be expected since the GreetingServiceImpl has not been provided a MessageRepository. In the next two steps, you will add annotations to drive the dependency injection and initialization respectively.
Step 5:
Provide an @Autowired annotation on the GreetingServiceImpl's setter method, such as:
public void setMessageRepository(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
Then, add the 'annotation-config' element (from the new 'context' namespace) to your configuration:
<context:annotation-config/>
<bean class="blog.GreetingServiceImpl"/>
<bean class="blog.StubMessageRepository"/>
</beans>
Rerun the tests. They will still fail, but if you look closely it's a new problem. The assertions fail, because the messages being returned are null. That means that the 'messageRepository' property has been set on the greeting service! Now, the StubMessageRepository simply needs to be initialized.
Step 6:
Spring provides a couple options for initialization callbacks: Spring's InitializingBean interface or an 'init-method' declaration within XML. As of Spring 2.1, JSR-250 annotations are supported - providing yet another option: @PostConstruct (and the @PreDestroy annotation can be used for destruction callbacks as you will see shortly). In the StubMessageRepository, add the annotation to the initialize method:
public void initialize() {
messages.put("English", "Welcome");
messages.put("Deutsch", "Willkommen");
}
Rerun the tests. This time they should pass!
Step 7:
The @Autowired annotation can also be used for constructor-based injection. If you'd like to experiment with that option, remove the setter method from the GreetingServiceImpl and add this constructor instead (then rerun the tests):
public GreetingServiceImpl(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
If preferred, you can even use field-injection. Remove the constructor, add the annotation directly to the field, and rerun the tests. The code should look like this:
private MessageRepository messageRepository;
Step 8:
Add a JDBC-based repository implementation of the MessageRepository:
private SimpleJdbcTemplate jdbcTemplate;
@PostConstruct
public void setUpDatabase() {
jdbcTemplate.update("create table messages (language varchar(20), message varchar(100))");
jdbcTemplate.update("insert into messages (language, message) values ('English', 'Welcome')");
jdbcTemplate.update("insert into messages (language, message) values ('Deutsch', 'Willkommen')");
}
@PreDestroy
public void tearDownDatabase() {
jdbcTemplate.update("drop table messages");
}
public String getMessage(String language) {
return jdbcTemplate.queryForObject("select message from messages where language = ?", String.class, language);
}
}
Notice that in addition to @PostConstruct for initialization, this is using @PreDestroy to mark a method to be called on destruction. One thing is unclear from this implementation: how will the SimpleJdbcTemplate be provided? One option would be to provide a bean definition for the template. Another option would be to somehow provide a DataSource implementation to the template's constructor. Add the following (annotated) method:
public void createTemplate(DataSource dataSource) {
this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
This demonstrates dependency injection working with an arbitrary method (not a traditional 'setter'). This will be tested in the course of the next step.
Step 9:
In Spring 2.1, "candidate" beans can even be discovered rather than provided explicitly in the XML as above. Certain annotations are recognized by default. This includes the @Repository annotation as well as a new @Component annotation. Add those two annotations to JdbcMessageRepository and GreetingServiceImpl respectively:
Then modify the XML file by removing the existing explicit bean definitions and simply adding a component-scan tag:
<context:component-scan base-package="blog"/>
</beans>
Then, add just the DataSource bean definition and the new tag for configuring property placeholders:
<context:component-scan base-package="blog"/>
<context:property-placeholder location="classpath:blog/jdbc.properties"/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
… and the jdbc.properties file itself:
jdbc.url=jdbc:hsqldb:mem:blog
jdbc.username=sa
jdbc.password=
Rerun the tests, and you should see the green bar even though only the data source has been defined in XML.
Step 10:
Finally, add an aspect (the @Aspect annotations are also automatically detected by default):
public class ServiceInvocationLogger {
private int invocationCount;
@Pointcut("execution(* blog.*Service+.*(..))")
public void serviceInvocation() {}
@Before("serviceInvocation()")
public void log() {
invocationCount++;
System.out.println("service invocation #" + invocationCount);
}
}
And to activate automatic proxy generation, simply add the following tag to the xml:
Rerun the tests, and you should see the log messages!
NOTE: the scanning and configuration process can be initiated without any XML and can be customized (e.g. detect your own annotations and/or types). I will discuss those features and more in the next post.
In the mean time, I hope this post will serve its purpose well - providing hands-on experience with these new Spring 2.1 features. As always, we are looking forward to feedback from the community, so please feel free to leave comments!
domix says:
Added on May 14th, 2007 at 8:52 pm -QuoteReally nice post, Spring 2.1 rocks..
Hideyuki Suzumi says:
Added on May 14th, 2007 at 11:48 pm -QuoteGreat post!
How is the scope of beans defined?
choff says:
Added on May 15th, 2007 at 12:36 am -QuoteI like these
Magnus Heino says:
Added on May 15th, 2007 at 1:47 am -QuoteHow does @Autowired relate to @Resource?
Peter Veentjer says:
Added on May 15th, 2007 at 4:46 am -QuoteThe thing I always liked about Spring is that my sourcecode didn't depend on Spring. But I have the impression that this isn't as important for the Spring team anymore. Pojo's with annotations are not pojo's anymore.
Debasish Ghosh says:
Added on May 15th, 2007 at 6:26 am -QuotePeter - The nicer part is that Spring always gives you options (unlike some other frameworks). If you feel annotations intrude into your POJOs, you can always fallback on other options. I am still not very sure if we should remain so strict about the definition and interpretation of what constitutes a POJO, but localized metadata has some advantages. Of course there are issues like unit testing where I would not like to have Spring come along my way. It is interesting to find out what the Spring guys have to say about this.
Martin Koci says:
Added on May 15th, 2007 at 6:46 am -QuoteGreat news! @PostCostruct and @PreDestroy are very useful annotations. Btw. how does spring 2.1 relate to PitchFork - http://interface21.com/pitchfork/ ?
Craig Walls says:
Added on May 15th, 2007 at 8:47 am -QuoteA little word of advice for anyone trying this out with @AspectJ annotations: Don't be lazy with your pointcuts. If your pointcut is "execution(* *.*(..))" it won't work. That's because the pointcut will also match the aspect class itself and you'll get a message stating that there's a circular reference. Just doing my part to save you the trouble I encountered.
Thai says:
Added on May 15th, 2007 at 8:58 am -QuoteI like what Peter Veentjer said and from Martin Koci's post, I have a question: is there anyway to get rid of the @PostConstruct and @PreDestroy annotations in the Java file and declare it somewhere in the XML file?
Mark Fisher (blog author) says:
Added on May 15th, 2007 at 10:14 am -QuoteOn May 15, 2007 at 1:47 am, Magnus Heino said:
The @Resource annotation is also supported and can either resolve to a Spring-managed bean name (the default) or JNDI-name (for details, see: http://static.springframework.org/spring/docs/2.1.x/api/org/springframework/beans/factory/annotation/CommonAnnotationBeanPostProcessor.html).
The @Autowired annotation can also be used for constructor-injection.
Ben Hale (blog author) says:
Added on May 15th, 2007 at 10:38 am -QuoteOn May 15, 2007 at 6:26 am, Debasish Ghosh said:
Well one thing to remember is that annotations are just what you describe, metadata. Which means they have to be interpreted. So if you're running a true unit test, Spring isn't in the picture and the metadata is ignored. You do whatever injection you'd like as part of the test and Spring isn't around.
Mark Fisher (blog author) says:
Added on May 15th, 2007 at 10:48 am -QuoteOn May 15, 2007 at 4:46 am, Peter Veentjer said:
I want to emphasize that the annotation-driven configuration is an optional mechanism. XML will of course always continue to be supported, and Java Configuration provides another non-XML based alternative in a completely non-invasive manner (http://www.springframework.org/javaconfig). The annotations can be used in combination with XML (as demonstrated in Step 9 above), and it is always possible to provide user-defined annotations instead of the Spring defaults (@Component, @Autowired, etc). In the next post, I will provide some examples of such customization options as well as using other criteria (assignable types, regular expressions, etc.) instead of annotations for the scanning.
Ben Hale (blog author) says:
Added on May 15th, 2007 at 10:51 am -QuoteLet\'s also not forget that the Spring community aren\'t the only ones working on alternate configuration strategies. The grails folks have a groovy style of configuration that seems pretty cool: http://grails.codehaus.org/Spring+Bean+Builder
Joe Toth says:
Added on May 15th, 2007 at 11:27 am -QuoteThe new annotation driven injection is awesome. I've been waiting for a way to automatically wire up everything programmatically instead of declaratively.
From the example, one piece I see missing. Will there be a way to programmatically inject property values into fields?
To be replaced by something like…
public class MyAppDataSource extends DriverManagerDataSource {
@Autowired(propertyName="jdbc.driver")
private setJDBCDriver(String jdbcDriver) {
setDriverClassName(jdbcDriver);
}
… etc
}
Magnus Heino says:
Added on May 15th, 2007 at 11:53 am -QuoteI have the same question as Hideyuki Suzumi above; What about scopes?
Looking forward to more great blog posts!
blog.interface21.com is really great.
Costin Leau (blog author) says:
Added on May 15th, 2007 at 11:55 am -QuoteOn May 15, 2007 at 6:46 am, Martin Koci said:
At this point there isn't any direct connection as Pitchfork supports the EJB3 spec where the JSR250 annotations are used in a specific way (see the class and method annotations and inheritance rules that EJB 3 defines).
Also, both @PostConstruct and @PreDestroy in EJB3 context, depend a lot on the interceptors enabled on a certain session bean as well as the defaults specified in the EJB3 container (through XML files).
Mark Fisher (blog author) says:
Added on May 15th, 2007 at 12:59 pm -QuoteCurrently, the scanned bean definitions will be singleton scope. Note however that the annotation-driven metadata can be merged with metadata in XML so that scope can still be provided in the XML (as well as any explicit properties).
Rodrigo Urubatan says:
Added on May 15th, 2007 at 2:24 pm -QuoteI think this is a great idea to have this on spring core.
this is almost all that I did in the spring-annotations project …
The only thing I do not understand is why when I suggested to merge spring-annotations with spring framework no one liked the idea, and now this is in the spring core …
but as I said it is great to have this feature in the spring core.
the only thing missing is the ability to choose the scope and other attributes for the scanned beans.
PS.: not I think that the spring-annotation project is almost deprecated.
Rodrigo Urubatan says:
Added on May 15th, 2007 at 3:04 pm -Quotethe Spring-Annotations (http://sannotations.sourceforge.net) has the bean scanning feature, and it has support for defining scope and other bean properties in the annotation too.
I have already suggested it before, but what do you think about merging the spring-annotations core (the engine with the annotations scanning, and some other things), with the Spring Framework?
Hideyuki Suzumi says:
Added on May 15th, 2007 at 7:35 pm -QuoteThis is very inconvenient, I think.
Rodrigo Jardim says:
Added on May 15th, 2007 at 9:26 pm -QuoteYes, that`s why with spring-annotations you can choose which scope your scanned bean will be …
and that was already working when I tried to submit that eature to spring last year, and they told me that it would never be in the spring core, because Spring is a DI container, and with this kind of annotation it will become a service lookup framework …
and now they put it on spring core, without giving any credit to whom first told to do it …
Hideyuki Suzumi says:
Added on May 16th, 2007 at 12:21 am -QuoteCurrently, @Autowired and @Required cannot be specified on a class,
though @Transactional can be specified on a class.
I think it is useful if it is possible to apply to all setters at a time.
Magnus Heino says:
Added on May 16th, 2007 at 1:46 am -QuoteWouldn't it make sense to scan for @Configurable too?
Or is that included in http://opensource.atlassian.com/projects/spring/browse/SPR-2492 ?
Colin Sampaleanu (blog author) says:
Added on May 16th, 2007 at 1:44 pm -QuoteRodrigo,
You wrote a similar question in this Jira entry:
http://opensource.atlassian.com/projects/spring/browse/SPR-3486
Mark has replied there, but I'll quote his reply:
"""Spring's annotation-driven configuration code has been introduced in the first milestone release of version 2.1. As a milestone release it will definitely continue to evolve, but it is in no way a "crippled" implementation. The implementation model we have chosen does not follow the approach of the spring-annotations project. We did not feel that mirroring the XML elements and attributes within annotations was the correct approach for our needs. We have a strong responsibility to provide support that will work in a complementary way with other Spring configuration options (including XML bean definitions as well as Java Config), and we are providing support for JSR-250 annotations with a clear focus on consistency. Since we are taking a different approach than the spring-annotations project, it did not make sense for us to consider re-using some of the spring-annotations code. As always, we welcome feedback from the Spring user community and for Spring users to build upon Spring in any way; it's great that people are trying to push the boundaries of what Spring can do. That said, after considerable thought and prototyping on how to best do annotation-driven dependency injection in a manner that is consistent with Spring in general, the Spring team decided this approach - implemented from scratch - was the best choice."""
I think Mark's reply is pretty good on its own, but I can comment along the same lines. It's absolutely great the other projects try to build on Spring functionality to implement things that people need, and it's a testament to the flexibility of IoC, and how Spring was built, that it's possible to do this kind of stuff without having to modify Spring. However, that doesn't automatically mean when/if the core project tries to approach the same problem space it makes sense to reuse the same approach or even the code as somebody else may have used. Last year, while we had some decent experience in implementing annotation driven injection via the Pitchfork project, we first of all did not think it was the right time to do any sort of annotation driven injection in core Spring itself, and fundamentally the spring-annotation model didn't feel quite right either. This year, while we think many/most people will prefer to stick to XML, there is some demand for an annotation driven approach, and we're trying to meet this need (along with trying alternative Java-focused approaches like Java Config), in the fashion that feels best to us.
I do think it's a bit disingenuous to try to imply that this new code uses or borrows from spring-annotation (with or without credit given). None of us have ever been in the code for spring-annotation, the model is pretty much different, this problem space has been tackled by other projects (EJB 3, our own Pitchfork, etc), and we've thought a lot about how to approach this, and hopefully have come up with a usable solution.
Colin
Colin Sampaleanu (blog author) says:
Added on May 16th, 2007 at 1:47 pm -QuoteOf course I forgot to mention Bob Lee's Guice in my last paragraph above.
Colin
Colin Sampaleanu (blog author) says:
Added on May 16th, 2007 at 1:55 pm -QuoteThe other thing that needs emphasizing here (as Mark has said a few times) is that this stuff is going to continue to evolve. This is just an M1 release and this is just an initial cut of functionality that we feel pretty good about.
For example, as Mark has said to me previously, it would take about a minute to support defining scope with an annotation, but right now we're not sure we necessarily think that's actually appropriate (should a bean really know about its own scope, is that not something for the deployer/configurer to worry about?). So for this release we've left scoping as something to be configured only via XML, which is actually quite easy to do…
Colin
Hideyuki Suzumi says:
Added on May 16th, 2007 at 7:45 pm -QuoteWhy is @Autowired good?
Guilherme Silveira says:
Added on May 17th, 2007 at 8:01 am -QuoteWhy is there @ annotations for lifecycle methods instead of defining them by an interface?
It usually allows the programmer to create methods as "stopp" or even "finalize".
Such lifecycle interfaces are troublesome when they contain 10 methods, but a start/stop interface does not seem to hurt anyone and would allow all projects to have the same standard method names for such callbacks.
Any thoughts?
Ben Hale (blog author) says:
Added on May 17th, 2007 at 9:24 am -QuoteThose lifecycle interfaces already exist. The org.springframework.beans.factory.InitializingBean interface contributes an afterPropertiesSet() method, the org.springframework.beans.factory.DisposableBean interface contributes a destroy() method, and the org.springframework.context.Lifecycle interface contributes isRunning(), start(), and stop() methods (typically used for objects dealing with threading).
These interfaces are still detected and honored as they always have been by Spring, even when using the annotation scheme. The use of JSR-250 lifecycle annotations is just to add support for the JSE standard.
Colin Sampaleanu (blog author) says:
Added on May 17th, 2007 at 9:44 am -QuoteTo clarify on Ben's point about the JSR-250 annotations, these actually are a standard part of Java EE from Java EE 1.5 (last May), and then are included in Java SE 6 (JDK 1.6).
Colin
Colin Sampaleanu (blog author) says:
Added on May 17th, 2007 at 11:14 am -Quote>> What do you think about AridPOJO-like xml configuration?
Chris Richardson and I and a few of the other Interface21 people had a nice conversation at JavaOne. It was ironic that Chris came out with his article/implementation a few days before this stuff (above) made it into CVS as a first cut.
It's an interesting approach to some of the same problems (i.e. trying to reduce XML). We've discussed (amongst ourselves, and with Chris), the use of AspectJ expressions to do filtering of stuff, in order to decide what to match on. In the fear of introducing too many approaches, we're going to hold off for the time being, but we're definitely going to try to work with Chris to get feedback on the best annotation driven approach.
Btw, Chris is going to be presenting at SpringOne in Antwerp next month!
Regards,
Colin
–
Attend SpringOne 2007, Interface21's developer conference covering the Spring Portfolio products.
42 Sessions in 3 Parallel Tracks
June 20 - 22, 2007 - Antwerp, Belgium
www.springone.com
Colin Sampaleanu (blog author) says:
Added on May 17th, 2007 at 2:20 pm -Quote(edited 2007-5-18 to fix typos and clarify)
>>should a bean really know about its own scope, is that not something for the deployer/configurer to worry about?
>Why is @Autowired good?
Well it\'s not
Just kidding there… Now most of the Spring team do think that using the annotation approach is unnecessarily invasive, given the existence of alternative approaches (XML or the Spring Java Config) that are completely non-invasive. That said, there is definitely some demand for the annotation driven approach; some people know they want to use it, some people at least want to try it. So it\'s important that Spring offers best of breed options for XML, annotation, and external Java (aka Spring Java Config) based dependency injection.
Anyway, @Autowire is one thing, it says, I expect somebody else will wire me. Setting your own scope takes things to another level. Arguably a bean might know about its appropriate scope sometimes, but other times it is clearly up to the deployer to pick. Think about an object that may be in a regular scope in some circumstances, and in Request or Session scope other times. What happens if you bake that into the object? We will almost certainly add the ability to apply scope via an annotation, but people need to be very careful in making the decision to actually use that annotation.
Regards,
Colin
Mark Fisher (blog author) says:
Added on May 18th, 2007 at 11:05 pm -QuoteScope support has been added as of the latest 2.1-m2 snapshot (download here: http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR)
Scope can be determined from the value of the @Scope annotation (e.g. @Scope(\"request\")), and the default value is singleton.
Please note that the ScopeMetadataResolver is a strategy interface, and custom implementations may be provided to the bean definition scanner (the default is AnnnotationScopeMetadataResolver).
Sam Brannen says:
Added on May 20th, 2007 at 7:12 am -QuoteHi Mark,
First off, great work! I especially appreciate the support for the standard annotations defined by JSR 250, as that allows one to avoid too many dependencies on Spring APIs. Secondly, I have a few questions:
1) When will the XSD file be available via http://www.springframework.org/schema/context/spring-context-2.1.xsd?
My XML editor in Eclipse is bugging me about not being able to find the file. I added a custom entry to my XML Catalog in MyEclipse, and that serves as a nice work-around, but I imagine others will want the XSD available on the web soon as well.
2) Are you planning on adding support for multiple locations for the new context:property-placeholder tag? If not, I think that would be a nice add-on.
regards,
Sam
Peter says:
Added on May 21st, 2007 at 2:37 am -QuoteNice article to me.
Thanks.
Mark Fisher (blog author) says:
Added on May 21st, 2007 at 11:16 am -QuoteOn May 20, 2007 at 7:12 am, Sam Brannen said:
The XSD is now available.
On May 20, 2007 at 7:12 am, Sam Brannen said:
The 'location' attribute does actually accept a comma-delimited list of properties file locations (as Spring Resource locations).
-Mark
Kalyan Dasika says:
Added on May 21st, 2007 at 1:35 pm -QuoteMark,
I left a question on the spring forums. Perhaps you can help me with that. It is related to your blog.
http://forum.springframework.org/showthread.php?t=39018
Jacky.Song says:
Added on May 24th, 2007 at 10:06 pm -QuoteGood work! Expecting final release…
Ivan says:
Added on May 31st, 2007 at 1:36 pm -QuoteI'm here for another vote on the annotations thing. It is very important to me, and central to my usage of Spring, that I have non-annotation options. The second I see one, I back off from that as a potential solution. Configuration and aspects have nothing to do with application code, isn't that the goal?
Ivan says:
Added on May 31st, 2007 at 2:07 pm -Quote@Debasish Ghosh
Localized metadata defeats the purpose of extracting anything into a config. It's a very hard line, or it isn't one at all.
@Colin
If what you're giving us is a essentially a package-level configuration option then we should have the power to decide whether or not we want package-level scope definitions. An override method would be nice on some, but this has some powerful implications.
I can create a package of beans I know will be prototyped and specify them as such. Because they will be such one-offs, I also autowire them into where they would be going..
It seems like having this ability would really cut down on the amount of xml needed.
Chris Richardson really got it 90% of the way there. I think its important to not forget his very practical initial implementation. Too much thinking and it starts veering off in an ivory tower direction.
victor yao says:
Added on June 21st, 2007 at 6:13 am -QuoteHi Mark,
Tried to run the code but failed to compile on @PostConstruct annotation. I am using Spring with "spring-framework-2.1-m2-with-dependencies.zip" download. Is this annotation work with the above mentioned version?
Thanks Victor
Mark Fisher (blog author) says:
Added on June 21st, 2007 at 7:15 am -QuoteVictor,
You need to have the annotations within the \'javax.annotation\' package on the classpath. These are included in Java SE 6 - or if you are using Java 5, you can add the \'common-annotations.jar\' (in \'j2ee/lib\' of the distribution).
Olia says:
Added on September 26th, 2007 at 2:41 pm -QuoteHi,
should annotation-based AspectJ work with Java6? I keep getting an error about it, and I am running with Java6:
[java] org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.AspectJPointcutAdvisor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: error the @annotation pointcut expression is only supported at Java 5 compliance level or above
[java] Caused by:
[java] java.lang.IllegalArgumentException: error the @annotation pointcut expression is only supported at Java 5 compliance level or above
[java] at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:315)
[java] at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:189)
[java] at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:176)
[java] at org.springframework.aop.aspectj.AspectJExpressionPointcut.getMethodMatcher(AspectJExpressionPointcut.java:162)
[java] at org.springframework.aop.aspectj.AbstractAspectJAdvice.buildSafePointcut(AbstractAspectJAdvice.java:181)
[java] at org.springframework.aop.aspectj.AspectJPointcutAdvisor.(AspectJPointcutAdvisor.java:51)
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
[java] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
[java] at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
[java] at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:85)
etc..
Ferry says:
Added on March 10th, 2008 at 4:58 am -QuoteHi Mark,
The cost of @Transactional seems very high. If I have a client that call a service that is annotated with @Transactional, it will at least required 300ms (this is relative) just to called the very simple method.
While I don't really need a transactional method, but the problem is that I will get the "Session is closed" exception whenever I called something like this :
em.read(); followed by em.merge(). It seems that without the @Transactional, I'm not able to use the em(EntityManager) more than once in one conversation.
What is the best practice for this issue ? Can I avoid the @Transactional ? It has much better performance if I put the @Transactional at the caller side, but this is not I want.
Thanks, and sorry if this is not the right place to ask :p
df fdsfsdf says:
Added on March 17th, 2008 at 5:13 am -Quotedsfds fds