Does anybody know what Spring JAR (and where to find it!) contains the functionality for Spring's so-called "meta-annotations". As this article shows, these cool "new" (well, sorta) constructs allow code like this:
#Service
#Scope("request")
#Transactional(rollbackFor=Exception.class)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyService {
}
#MyService
public class RewardsService {
…
}
Basically, I have a Swing app that does not currently use Spring. I have a sudden requirement change that would be made supremely-easier if I could use these annotations.
So I'm just looking for the smallest, minimally-invasive Spring JAR where this functionality can be found. If absolute-need-be, I can use the entire Spring JAR, but it would be a very heavy-handed solution. It would be nice if Spring released a smaller JAR with smaller-scope functionality.
I'm browswing Maven Repo and see spring-core which contains a package called:
org.springframework.core.annotation
But upon inspection of the API docs it doesn't seem to be what I need...
Ancillary question: is it even possible to use these meta-annotations as standalone constructs, or do I have to use them along with, say, Spring DI or AOP or other major parts of the Spring framework?
Thanks in advance!
The annotations you want will be with the jar it is related to. For instance, the annotation org.springframework.transaction.annotation.Transactional will be in the spring-transactions artifact.
Meta-annotations are not really different from regular annotations other than the fact that Spring now detects Annotations on annotations whereas it didn't before. Whether annotations "work" or not depends on what is looking for them (in this case something in the Spring context).
For further reading see Annotation-based container configuration in the Spring framework reference.
There is project on github which is trying to provide meta-annotation functionality.
https://github.com/dblevins/metatypes/
Related
I want to know how to discover all qualifying beans that should be implemented when using some component together Spring.
For example, when using JPA and Spring Boot we need beans as like as sessionFactory and dataSource (Any more? I don't know, see It?).
Is there any official place where I can check the pre requisite list of beans?
I've made many searches through the official schemas and I couldn't find a pattern for bean dependencies.
After some time I've come into some steps that helped me and maybe help others. I'm answering this also because there are a lot of material related to Beans in XML files and in a Maven project, but if you try to create a XML free project, things become more rare when using Spring.
Notice: in deep Spring doesn't cares if the bean is an annotation or inside a XML. I preferred these configurations as a personal choice.
Some project details:
Gradle (project configurations are in application.properties file)
Java 8
Bean class(es) for src and for test. Note: You can use extends among them.
In case of doubt, https://start.spring.io/ an awesome way to create from nothing a spring project with your dependencies. Gradle format dependencies usually can be found at maven repository nearby the maven format.
Resolution:
Create a unit test (e.g JUnit) to just test your layer. For example mine was persistence layer.
Be careful to add each framework(that is going to be loaded by Spring) at once. Dealing with many unconfigured frameworks at same time would lead to caos since may be hard to figure out from where the Bean class should come from.
When the test fails look at his bottom of your console. Some exception will be thrown saying that a Bean with some name is missing. This are the guys you need.
Create a method typed with #Bean inside a class typed with #Configuration. This method must returns variable/object type complained in the exception message. Additional annotations maybe be required, for example, #EnableTransactionManagement for JPA beans.
Bonus:
Spring is deeply connected to IoC (dependency injection) and containers. Take a look at this contents because when you see that you realizes why to use Beans.
is it possible to write a "maven plugin" or something like that which changes the .java at compile time?
For example:
#Entity
... class ... {
#Id
long id
}
I would like to comment out all the Annotations and Create a ORM-Mapping.xml / Persistence according to the entitys
The annotations are mostly based on the configuration files which enable/disable their recognition.
Use the Spring profiles to distinguish the configuration classes. If the special profile will appear, no configuration classes will be recognized. The solution requires to make all the configurations configurable according to the Spring profiles.
#Configuration
#Profile("noAnnotations")
public class SomeConfigurationClass
It's possible. Project lombok modifies compiled code however there's no exposed API to do that. (See How does lombok work?) Which is what you want if you have to strip annotations. Disabling all annotations at runtime is probably not reasonable. If you just want to generate something from annotations found in compiled classes that is much simpler
What you describe sounds like you're looking for something like a C/C++ preprocessor/templating - feature?
Maybe Annotation Processing can help you https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/Processor.html
Apart from that - inferring a persistence.xml from your entities annotations is something the Spring Framework does.
I am using Spring Declarative Annotation based caching in my project .
applicationContext.xml
<cache:annotation-driven />
Currently, everything works perfectly using spring annotation based caching.
We use ehCache and ConcurrentHashMap based underline caching mechanism in development and local environment.
Now there is a requirement in project where I need to update the behavior of Spring cache framework with some specific business requirements.
I wonder if any one help me to figure it out how can I replace
<cache:annotation-driven />
this annotation with any spring class definition where I can customize the behavior?
Check out org.springframework.cache.annotation.EnableCaching.
Look at the comments in the source code.
It does the equivalent of the < cache:annotation-driven /> but in spring java config.
You will prolly need to override this class: org.springframework.cache.aspectj.AnnotationCacheAspect
Its responsible for wiring the advise in.
This answer lead me in the right direction. The thing that I found about the inner workings of the caching support from spring is that its not Dependency injected outside of the cacheManager and KeyGenerator implementations. I wanted to subclass/extend the CacheAspectSupport and found that this class is first extended by CacheInterceptor but then that class is created using new statements in a class ProxyCachingConfiguration. To be able to replace the one class/method would take replacing a whole list of classes which doesn't sound very spring friendly (admittedly i could be missing something).
What i was expecting from the replacement of the line was a fully listed out set of spring beans that composed all of the AOP pointcuts, advice/aspects, etc. that make up the caching support, but it seems like this is alål just statically created classes with tight coupling between each other.
I need to configure different #Alternatives, #Decorators and #Injectors for different runtime environments (think testing, staging and production servers).
Right now I use maven to create three wars, and the only difference between those wars are in the beans.xml files. Is there a better way to do this? I do have #Alternative #Stereotypes for the different environments, but even then I need to alter beans.xml, and they don't work for #Decorators (or do they?)
Is it somehow possible to instruct CDI to ignore the values in beans.xml and use a custom configuration source? Because then I could for example read a system property or other environment variable.
The application exclusively runs in containers that use Weld, so a weld-specific solution would be ok.
I already tried to google this but can't seem to find good search terms, and I asked the Weld-Users-Forums, but to no avail. Someone over there suggested to write my own custom extension, but I can't find any API to actually change the container configuration at runtime.
I think it would be possible to have some sort of #ApplicationScoped configuration bean and inject that into all #Decorators which could then decide themselves whether they should be active or not and then in order to configure #Alternatives write #Produces methods for every interface with multiple implementations and inject the config bean there too.
But this seems to me like a lot of unnecessary work to essentially duplicate functionality already present in CDI?
edit
Ok, I realized I'm a bit stupid... of course it is possible to add stereotypes and inteceptors at runtime using the CDI extension API:
void beforeBeanDiscovery(#Observes BeforeBeanDiscovery bbd) {
bbd.addInterceptorBinding(...)
bbd.addStereotype(...)
}
But what I didn't find was an API to add a decorator. The only thing I found was to activate all #Decorators in the beans.xml, then observe
public <T> void processAnotated(#Observes ProcessAnnotatedType<T> event)
and call
event.veto()
if I don't want a #Decorator to be active.
You might want to take a look at JBoss Seam, specifically the Solder sub-project.
It allows dependency driven CDI resolution, so that certain beans are only available if other beans or resources are available. (Class A if "dataSource" is available, Class B if "entityManager" is available)
Since it's open source, you can also take a look at how they wired that together, and use that knowledge as a basis for writing your own extension if needed.
If you're using JSF, I would highly recommend using SEAM-JSF as well, as it gets rid of the clunkiness of having two injection frameworks (JSF DI/CDI) and allows CDI beans in JSF scopes.
This week I've been trying to learn Spring, JBoss, Maven, JPA and Hibernate and I've had a lot of fun with it. I am somewhat confused over the many different ways to inject resources in a class though. Until this week I was not even aware that you could inject resources in any other way than using the <property> tag in your Spring XML configuration.
<bean id="catalogService" class="com.idbs.omics.catalog.service.CatalogService">
<property name="termDao" ref="termDao"></property>
</bean>
When I started experimenting with JPA I encountered #PersistenceContext, but that seems to be a special case so fair enough. Then I started reading up on Spring's testing framework and I saw the first example that used #Resource(name="catalogService") and then in a Web Service example #Autowired crashed the party!
**The Question!**
So what is the difference between all these and is there right and wrong situation to use them in? I guess I'm looking for a best practice here.
Cheers all
#Autowired, #Resource and #Inject
I think the part of the Spring Reference that you need to read is
3.9 Annotation-based container configuration
There are many sets of similar annotations. Often, there is a Spring and a non-Spring version that do the same thing. Spring tries to embrace standards whenever they are available, but often the Spring guys came up with their own ideas before a standard appeared. Example: Spring supports its own #Autowired annotation, but also the new #Inject annotation from JSR-330, as well as the JSR-250 #Resource annotation (all of which can be used to do the same thing).
The key concept here is that Spring doesn't force you to use its own code, but supports many different ways without coupling your application to Spring. (There are still a few annotations that have no non-Spring equivalent, like #Transactional, but if you want to, you can add that functionality via XML instead, so you can keep your application 100% Spring free and still use many convenience annotations and of course Spring wiring and lifecycle management behind the scenes.
The other aspect of this is when to use annotations and when to use XML spring wiring files.
My view is that this is a trade-off between code readability and the ability to reconfigure.
If you use annotations, then you can see from just the source code what is wired to what. By contrast, if you use XML wiring files, you have two places to look.
If you use XML wiring files, you can make configuration changes by modifying (or with Maven overlaying) the XML wiring files. If you are bold, you can even do this on a deployed webapp. By contrast, changing the IoC wirings when annotations are used requires you to modify the Java files and recompile.
(Aside: in the case of the second bullet, the ideal situation would be to have a nice GUI-based tool for reconfiguring the wirings that could be run in either your development sandbox, or the deployed webapp folder. Does anyone know of such a tool?)