Use ByteBuddy to change package of annotated class in Spring app - java

I want to change the package of classes that have been annotated with a particular annotation. I want to do this so that they can't be picked up by Jersey. I'm wondering if this is achievable within a Spring (Boot) application. If so, where is the best place to add this? I had originally wanted to do this in a ImportBeanDefinitionRegistrar so I could add an EnableXXX annotation on a config class, but I think that might be too late in the Spring lifecycle to redefine classes.

Yes, Byte Buddy allows you to change the name of any instrumented type. You can create an AgentBuilder to match all types that carry your annotation and change their package name using the DSL.
Do however note that any references to this class would not be updated automatically and other implications of a package change would be rather unpredictable. Generally, I would not recommend you to go down that route.

Related

Is there a way to ignore Custom annotation in SpringBoot bean config?

I am using a dependency JAR in my project which has a custom annotation "#monitor"
This annotation is being used at a lot of places in the code.
Going forward, I would like to perform a quick test if there are any performance improvements if we ignore this annotation(As there are reflection api calls due to this).
I do not want to remove annotation classes from the dependency JAR as other projects might be using this. I also do not want to go to every method in my code or inside JAR to remove the "#monitor" annotation from methods.
Is there a way in SpringBoot2 to ignore a particular annotation from a spring configuration class?
Is there a way in SpringBoot2 to ignore a particular annotation.

How take classes with some annotation in specific package

I write own DI/IoC library on java. I want to take classes which have some annotation (e.g. my own annotaion) in given package to scan, like in Spring IoC. But reflection from jdk is not appropriate, because i can't traverse through package. I took decision to use SimpleFileVisitor to take classes, but i don't want to use this "crutch". How to take classes with specific annotation in given package?
You must use Reflection lib form google.

auto-configuration adding PropertySource in spring-boot

I want to add a custom PropertySource (the class, not annotation). Annotation is not sufficient as it only handles file sources.
The approach which works is to define own ApplicationContextInitializer and add proper declaration to META-INF/spring.factories. ApplicationContextInitializer just uses:
Environment.getPropertySources().addLast(...)
But there are some drawbacks, mainly:
It is always run, but the preferable behaviour would be to only run if certain conditions are met (#ConditionalOnClass, etc)
How to achieve that? Ideally I'd write my autoconfiguration with #Condition... annotations and inside declare such initializer (preferably Ordered).
Edit:
In my particular case I want to define Archaius PolledConfigurationSource, but only if Archaius is on the classpath - that's why I'd like to use #ConditionalOnClass together with a listener on an event very early in the lifecycle.
You could have an intermediary class - part of your application, let's call it the "ProviderConfigurer" - of which goal will be to load a Service (packaged in a separate jar with META-INF/services/targetSPi) that in turn will load Archaius.
So to activate Archaius you will have to place 2 jars instead of one, but then the ProviderConfigurer will be able to load the property source provided by the Service (the API will be part of the interface you will have to define...) if any is discovered in the class path and do nothing in case the Service doesn't find any class implementing the SPI you will define for the purpose.

Java based dependency injection in Spring

I'm working in a webapp and this is the first time that I'm using Java based configuration. I have a bunch of class to configure all:
ApplicationContext
PersistenceContext
SecurityContext
WebAppInitializer
WebMvcContext
Now I'm defining Spring Data repositories and the service layer so I need to inject the repositories there. Normally I would use Autowired but I've read that it is preferable to define the injections manually so the question is, where?
Maybe neither of the previous configuration classes is suitable for such task but, do I have to create a single class to define all the injections or is better to have on for each function? What happens if the project grows too much?
I think that the main question would be what is best way to organize dependencies in a Spring project. What do you do?
I add here an image of the structure of the project as a petition. I'm trying to decouple layers and now I need to inject UserRepository to UserService.
No, I would not define a single class to do all the injections. All your classes are coupled that way.
I don't understand what "define the injections manually" means. You have to specify them in either XML or annotations. There's no other way that I know of.
You don't say if you're using XML or annotation configuration. I find myself using the latter more of the time, with only enough XML configuration to tell the Spring app context to scan for annotations.
The Spring idiom would have you specify your configuration in layers if you're using XML. It's a moot point for annotations, because they go into your source code.
Your application will read the Spring context on start up, instantiate all the beans, and wire together the necessary dependencies. You're good to go from then on.
I disagree with the link you provided. Avoid autowiring? No.
The article said that he recommends using XML configuration for large projects. This is a very small project at this point. It seems to me that auto wiring with annotations would be fine even by the article's author's words.

spring and aspectj, intercept method of a non-proxy object

i want to intercept method from a non-proxied object.
I have a class instance MyClass myClassInstance=new MyClass() and i want to intercept call of myClassInstance methods.
I know all works good with proxies, but i need aspect on non proxied.
Is this possible?
Thanks.
It is possible, but it is not desirable.
You can use #Configurable and AspectJ will intercept calls. Read the 7.8.1 Using AspectJ to dependency inject domain objects with Spring section of the docs about it.
In short - AspectJ plugs some "magic" either compile-time or load-time (with a respective weaver), which modifies the classes so that they become part of the spring context.
As of why I think it is undesirable - this is dark magic that happens by modifying the classes' structure. It's not an object-oriented approach, and I think it will be hard to support. Imagine 6 months later a colleague of yours is debugging a nasty issue. It could take days before he realizes this magic is happening. This opinion is subjection though. The functionality is there and if you need it - use it.
Using Spring, I do not believe so (I appear to be wrong), using AspectJ I believe you can as long as you compile all the code with the AspectJ compiler. However I have never tried it.
You can enable load time weaving in Spring. Then the class loader will weave whatever aspects you define into your classes when they are loaded - regardless of whether they are being created by Spring.
You'll need to enable LTW by adding this line to your context file:
See:
http://static.springsource.org/spring/docs/3.0.0.M4/spring-framework-reference/html/ch07s08.html#aop-aj-ltw

Categories

Resources