I have a question regarding how to implement Marker interface through spring. I need to point my marker interface to its implemented classes. Itself marker interface dont have any of function declaration.
interface A {
/* No Method declaration */
}
#Component("c")
Class B implement A {
void function1(){ .. }
void function2(){ .. }
}
#Component("c")
Class C implement A {
void function3(){ .. }
void function4(){ .. }
}
Now Some where in my business Logic, i would like to use #Autowire though my interface to point any of one implementation.
#Autowired
#Qualifier("b")
A aB;
#Autowired
#Qualifier("c")
A aC;
It dont work. Will you please help to implement in correct way…! I was expecting thorugh reflection it should give me the list of method available in the implemented classes but it dont.
Added More Details
The only thing i would like to do is, I would like to reply IResponse to my business methods, instead of different tyoe. Its ok for me if i would have to #Authowired direct to implementation like
#Autowired
B aB;
but i thought if there is some way my IDE and Spring do some logic and when i #Autowired my interface towards implementation then it should be able to pick my Implementation class and should show me the business methods. Its not magic, when i am using qualified. I just want from spring to show me business methods through reflection.
What is the point of injecting A exactly? You probably expect Spring to do some kind of "magic" when it injects the dependency. It does not. I will simply inject the bean that you have required if it can inject it. In your case, the Qualifer value gives a hint as to which bean instance spring injects.
Except the typo (it's #Autowired, not #Autowire), this code should indeed inject B and C. But as you declared them as being A in your code you'll get a simple java.lang.Object basically. That's just a fundamental principle of Java that is strongly typed language.
Related
#Component
#Aspect
#Slf4j(topic = "e")
public class NotVeryUsefulAspect{
#Pointcut("within(com.lc.aop.for_source.service.impl.AAopServiceImpl)")
public void pointCutWithinAAopService(){
}
#Pointcut("#within(com.lc.aop.for_source.service.XAnnotation)")
public void pointCutAnnotation(){
}
#Before("pointCutWithinAAopService()")
#Order(0)
public void adviceBeforeAAopService(){
log.debug("=======before aop service========");
}
#Before("pointCutAnnotation()")
#Order(-1)
public void adviceBeforeAAopService2(){
log.debug("=======before aop annotation========");
}
}
#Slf4j(topic = "e")
#Component("a")
#XAnnotation
public class AAopServiceImpl implements AopService {
#Override
public void m() {
log.debug("a -AAopServiceImpl");
}
}
Based on the advice-ordering
Consider collapsing such advice methods into one advice method per join point in each #Aspect class or refactor the pieces of advice into separate #Aspect classes that you can order at the aspect level via Ordered or #Order.
Do I understand correctly that the #Order does not work in this case? Why not suport the method level order?
I think this is a very simple function, but it can avoid some unnecessary misunderstandings about #Order
I would like to order advice by method level.
Well, the answer to your question is in the sentence directly before the one you quoted, in the very same paragraph of the very same info box:
When two pieces of the same type of advice (for example, two #After advice methods) defined in the same #Aspect class both need to run at the same join point, the ordering is undefined (since there is no way to retrieve the source code declaration order through reflection for javac-compiled classes).
That question should probably be posed to the chaps working on the springframework, that project is located at: https://github.com/spring-projects/spring-framework.
What you're asking for makes sense, but keep in mind that Order is meant to prioritize the loading of beans from the context, so it makes sense that Order needs to be applied to the Aspect and not the Pointcut itself.
If there are more than one implementation of an interface, then I would have to use #Qualifier to indicate which class I want to autowire with. Wouldn't it make more sense to autowire the class directly instead of interface?
This is what object oriented programming (especially abstraction and polymorphism) is about.
You build the classes independendent of concrete implementations and use an interface.
This allows you to change what implementation you use at any point.
Assume you have this:
public interface I{
void doSomething();
}
#Component("a")
public class A implements I{
public void doSomething(){
//...
}
public void doSomethingElse(){
//...
}
}
#Component("b")
public class B implements I{
public void doSomething(){
//...
}
}
If you use
#Autowired
private A yourVariable;
you might be tempted to use the doSomethingElse() method that is an implementation detail (by what reason whatsoever).
However, if you use
#Qualifier("a")
private I yourVariable;
this cannot happen as the method is not present in the interface.
This gives you the ability to swap the implementation at any time.
Wouldn't it make more sense to autowire the class directly instead of interface?
This pretty much depends on how exactly do you work with qualifiers but in general, the answer is "No", autowiring the class is a bad thing to do if you have an interface - you should always work by interface.
Here are the examples:
interface I { void foo(); }
class IImpl1 implements I {
void foo() {System.out.println("Impl1");
pubic void bar() {// another method - why not?}
}
class IImpl2 implements I { void foo() {System.out.println("Impl2"); }
Note, that an implementation IImpl1 has an additional method bar that doesn't belong to the interface I
Case 1:
#Component
public class Driver {
#Autowired
private IImpl1 i;
}
Here class Driver is tightly could to the concrete implementation IImpl1 in general I can call method bar from the Driver class because I have this implementation, but in this case if I'll have to switch the implementation of Driver in future you'll have to also change the code: both change the reference, and also get rid of calls to IImpl1.bar() that might be not that easy to do - its a change in logic. As a result, the whole polymorphic behavior is lost.
By far its the worst way to program.
Now, consider Case 2:
#Component
public class Driver {
#Autowired
#Qualifier("someLogicalName") // under the hood it spring will map it to IImpl1 but you don't know that here
I i;
}
In this case - the things are much better - you never couple the driver to the concrete implementation at the level of code. This means that in general its enough to change the qualifier to get another implementation. You can't call bar anymore - it won't compile.
You also do not know what the implementation will be injected. If in future the implementation of the component that actually implements the logic of "someLogicalName" will change (by that I mean that you'll create a new class IImpl3), you won't feel it here - you'll place that qualifier on that new class and all the places that use it will get that implementation automatically.
Case 3:
#Configuration
public class MyConfiguration {
#Bean
public Driver driver(#Qualifier("someLogicalName") I i) {
return new Driver(i);
}
}
public class Driver {
private final I i;
public Driver(I i) { // in real life this constructor can be generated by
// lombok or something, put it here for the sake of completeness
this.i = i;
}
}
This by far the most "clean" approach - conceptually its really similar to case 2, however in this case you don't place the qualifier at the level of Driver class at all, in fact, the class Driver is not even aware at the level of code / metadata that its related to Spring anyhow. Of course all the "advantages" of case 2 are also applicable here as well.
As Bloch states in Item 3 ("Enforce the singleton property with a private constructor or an enum type") of Effective Java 2nd Edition, a single-element enum type is the best way to implement a singleton. Unfortunately the old private constructor pattern is still very widespread and entrenched, to the point that many developers don't understand what I'm doing when I create enum singletons.
A simple // Enum Singleton comment above the class declaration helps, but it still leaves open the possibility that another programmer could come along later and add a second constant to the enum, breaking the singleton property. For all the problems that the private constructor approach has, in my opinion it is somewhat more self-documenting than an enum singleton.
I think what I need is an annotation which both states that the enum type is a singleton and ensures at compile-time that only one constant is ever added to the enum. Something like this:
#EnumSingleton // Annotation complains if > 1 enum element on EnumSingleton
public enum EnumSingleton {
INSTANCE;
}
Has anyone run across such an annotation for standard Java in public libraries anywhere? Or is what I'm asking for impossible under Java's current annotation system?
UPDATE
One workaround I'm using, at least until I decide to actually bother with rolling my own annotations, is to put #SuppressWarnings("UnusedDeclaration") directly in front of the INSTANCE field. It does a decent job of making the code look distinct from a straightforward enum type.
You can use something like this -
public class SingletonClass {
private SingletonClass() {
// block external instantiation
}
public static enum SingletonFactory {
INSTANCE {
public SingletonClass getInstance() {
return instance;
}
};
private static SingletonClass instance = new SingletonClass();
private SingletonFactory() {
}
public abstract SingletonClass getInstance();
}
}
And you can access in some other class as -
SingletonClass.SingletonFactory.INSTANCE.getInstance();
I'm not aware of such an annotation in public java libraries, but you can define yourself such a compile time annotation to be used for your projects. Of course, you need to write an annotation processor for it and invoke somehow APT (with ant or maven) to check your #EnumSingleton annoted enums at compile time for the intended structure.
Here is a resource on how to write and use compile time annotations.
I'm relatively new to Spring and I've got myself dug in a hole. I'm trying to model motor cars. Each model has it's own builder object, and I have a BuilderFactory that returns the correct builder based upon user selection from a web-app.
So I'm looking for suggestions on how to approach this problem where I need to create a number of individual vehicles, but I don't know what type of vehicle I'm going to need until run-time, and each vehicle needs to be unique to the user.
What I've got at the moment is shown below. The problem I have at the moment is that because the individual builders are singletons so are the individual vehicles. I need them
to be prototypes. I know it all looks pretty horrible so I'm sure there must be a better way of doing this.
The top level from the web-app looks like;
Vehicle vehicle = vehicleBuilderFactory.getBuilder(platform).build();
My vehicleBuilderFactory looks like this;
#Service
public class VehicleBuilderFactory {
#Autowired
Discovery3Builder discovery3Builder;
#Autowired
Discovery4Builder discovery4Builder;
// Lots of #Autowired statements here.
#Autowired
FreeLander2010Builder freeLander2010Builder;
public VehicleBuilder getBuilder(Platform platform) {
switch (platform.getId()) {
case 1: return discovery3Builder;
case 2: return discovery4Builder;
// Lots of case statements here
case 44: return freeLander2010Builder;
default: return null;
}
}
}
which itself looks pretty horrible. Each individual builder looks like;
#Service
public class DefenderBuilder implements VehicleBuilder {
#Autowired
Defender defender;
// Loads of Defender specific setters ommitted
#Override
public Vehicle build() {
return defender;
}
}
and finally the individual vehicle
#Service
#Scope("prototype")
public class Defender extends Vehicle {
}
The main problem now, is that because the builders are singletons, so are the vehicles, and
I need them to be prototypes, because User A's Defender is different to user B's Defender.
You can use Spring's ObjectFactory to have it service up prototype scoped beans from a singleton scoped bean. The usage is pretty straightforward:
#Component
class DefenderBuilder implement VechicleBuilder {
#Autowired
ObjectFactory<Defender> defenderFactory;
Defender build() {
return defenderFactory.getObject()
}
}
#Component
#Scope("prototype")
class Defender {
}
This returns a new Defender on each call to defenderFactory.getObject()
Without reading too much into the detail you say you want to produce Prototype beans from a singleton possibly with a look up in the IoC container.
Section 3.4.6.1 Lookup method injection of the Spring documentation describes how this can be done without losing the Inversion of Control i.e. without your beans knowing about the bean store.
I have made use of the ServiceLocatorFactoryBean to solve a similar problem before. The class level Javadoc is excellent and contains some clear examples.
Two things:
1) You can use proxy in order to hold narrower scope from wider scope(e.g prototype from singleton)
All you need is to define the prototype component with the relevant scope and proxyMode
You can read about scoped proxy here.
2) Another thing that I have noticed is that you plan to use multiple autowired annotation.
note that you can use autowire on a list of interface and it will autowire all components that implements this interface as discussed here.
Moreover you can add a platform id to the VehicleBuilder interface and then generate a map in the constructor e.g:
Map<Integer, VehicleBuilder> vehicleBuilders;
#Autowired
public VehicleBuilderFactory(List<VehicleBuilder> vehicleBuilders) {
this.vehicleBuilders = vehicleBuilders.stream()
.collect(Collectors(x -> x.getPlatformId(), x -> x));
}
in that way you can avoid the switch case.
I wanted to instrument a large number of classes to use with Spring Insight and instead of adding the #InsightOperation manually to the methods, I wrote an aspect to annotate the methods using point cuts.
However, this is not working. While the manual annotation affects the Spring Insight trace logging, the AspectJ method does not work.
Is there anything I am doing wrong here? (I decompiled the classes after aspectizing and do find the annotation in the class methods)
This is the aspect code snippet:
declare #method :public * com.example.IExample.execute(..) : #InsightOperation;
Spring documentation says this:
Use of the #Insight* annotations are
optional. They make it easy for end
users to define custom operation
frames and end points without needing
to create a plug-in. Because end user
code modification is required to use
the annotations, they are an option
for users who cannot or do not wish to
write aspects.
http://static.springsource.com/projects/tc-server/2.5/devedition/htmlsingle/devedition.html
So looks like the only way is to write a custom plugin
http://static.springsource.com/projects/tc-server/2.5/devedition/htmlsingle/devedition.html#tutorial-plugin
It is possible that the Insight LTW does not pick up your introduced annotations. I'll have to dig deeper on that.
In the meantime, you can try a more low-level annotation:
com.springsource.insight.collection.method.MethodOperationsCollected
If you look at the spring-core plugin, you will see that it does something similar:
public aspect RepositoryMethodOperationCollectionAspect {
declare #type: #Repository * : #MethodOperationsCollected;
}
An easy work around is to call another method from within your aspect method to continue executing the join point. I only tried calling a static method in a static class. See below my code for adding the #InsightOperation to all my JSON serialization.
My aspect:
#Aspect
public class JSONSerializerAspect {
#Around("call(* *.JSONSerializer.serialize(..)) && args(target)")
public Object serialize(ProceedingJoinPoint joinPoint, Object target) throws Throwable {
return JSONSerializationWrapper.serialize(joinPoint, target);
}
}
The static class it is calling:
public class JSONSerializationWrapper {
#InsightOperation(label = "JSON_SERIALIZATION")
public static Object serialize(ProceedingJoinPoint joinPoint, Object target) throws Throwable {
return joinPoint.proceed(new Object[]{target});
}
}
I'm using this myself and tested that it works.