Prioritize Autowiring of bean when there are multiple implementations - java

I have a service class XYZ.java that is Autowired in some other class ABC.java. I want to extend the service class XYZ and want to override some methods of this class.
Now, As i can not change ABC.java impl but want that when method of Autowired class is called then
i should call overriden method. How can i do that??
#Service
class XYZ {
public void m1(){
}
}
#Service
Class ABC{
#Autowired
XYZ xyz;
public void m2(){
xyz.m1();
}
}
Here i want to extend XYZ class
#Service
class XYZExtended extends XYZ{
#Override
public void m1(){
}
}
I want that when ABC.m2() is called it should call XYZExtended.m1() method.
Thanks in advance!!!

Related

How to generate Java call hierarchy in IntelliJ IDEA for overridden methods

I need to analyze the call hierarchy of methods in a Java Spring Boot application.
IntelliJ IDEA gets confused when I have:
a interface I declaring I.foo()
an abstract class A with implementation of I.foo()
several concrete classes B, C etc extending A and B overrides A.foo()
I'd like to get the call hierarchy of B.foo() however I get also all callers of C.foo().
If that matters, the classes are autowired similar to the following:
#Component
public class Caller1 {
#Autowired B b;
public void bar(){ b.foo()}
}
#Component
public class Caller2 {
#Autowired C c;
public void bar(){ c.foo()}
}
public interface I {
void foo();
}
public abstract class A implements I {
void foo(){..}
}
#Component
public B extends A {
#Override
void foo() {..}
}
#Component
public C extends A {
..
}
In IntelliJ IDEA, the call hierarchy of B.foo() includes both Caller1.bar() and Caller2.bar(). But I only want callers of B.foo() such as Caller1.bar().

How can I inject member annotations into my current instantiated object using Guice?

I am trying to inject a custom annotation using the Guice bindInterceptor into my currently instantiated Service.java class. Unfortunately when I call myMethod() the OnAnnotationEvent::invoke method is not called. How can I use Guice to call OnAnnotationEvent::invoke when the #OnAnnotation annotation tag is used on a method in the current class?
My code looks like this:
Service.java
//Instantiated by another service
public class Service extends AbstractVerticle {
private DataAccess dataAccess;
#Inject
public void setDataAccess(DataAccess dataAccess){
this.dataAccess = dataAccess;
}
#Override
public void start() throws Exception {
Guice.createInjector(new DataAccessModule()).injectMembers(this);
myMethod();
}
#MyAnnotation
public void myMethod() {
dataAccess.doStuff();
}
}
DataAccessModule.java
public class DataAccessModule extends AbstractModule {
#Override
protected void configure() {
OnAnnotationEvent onAnnotationEvent = new OnAnnotationEvent();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyAnnotation.class), onAnnotationEvent);
bind(DataAcess.class).to(DataAccessImpl.class);
}
}
OnAnnotationEvent
public class OnAnnotationEvent implements MethodInterceptor {
#Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Annotation called on: " + invocation.getMethod().getName();
return invocation.proceed();
}
}
MyAnnotation
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyAnnotation {}
I think that your problem is that you creating new injector that does not knows anything about your class. If you just need injector in your class - use #Inject private Injector injector;. If you need to load some aditional modules locally you just need to create child injector :
#Inject private baseInjector;
...
injector = baseInjector.createChildInjector(new Module1(),new Moddule2());
This doesn't work because your Service instance isn't managed by Guice. To make it work you must either create Service with Guice or annotate method doStuff in DataAccessImpl with MyAnnotation.

Issue with spring auto wiring with abstract class?

I have below abstract class.
Sender.java
public abstract class Sender{
public abstract void send(String id);
}
AttachSender.java
#Service("attachSender")
public class AttachSender extends Sender{
//It implements send() method here
}
SomeOtherClass.java
public class SomeOtherClass implements SomeOther{
#Autowired
private AttachSender attachSender;
}
Here i have an issue and the above code is not working.
My question is can i autowire the class instead of interface as above?
In my case AttachSender is a class but not interface.,
Thanks!
Yes, you can. If you have issues they should be elsewhere.
This thread deals with wiring a superclass, which might be of interest.
#service annotation looks wrong.
should be #Service

How to specify which subclass Spring should use

In my spring-based project I have a core module ('core') with a class
#Component
public class Superclass {
// stuff
}
instances of which are injected by type throughout the code like this:
public class AService {
#Autowired
private Superclass superclass;
// service stuff
}
I also have two other modules that depend on the core module and one of which (let's call it 'module1') extends Superclass:
#component
public class Subclass extends Superclass {
// overridden stuff
}
The other module ('module2') uses Superclass as is.
Now I want that when I compile and run 'child1' an instance of Subclass is used everywhere an instance of Superclass is expected. So I write a configuration class:
#Configuration
public class Module2Configuration {
#Bean
public Superclass superclass(){
return new Subclass();
}
}
When I run this I see both Superclass and Subclass instantiated which is definitely not what I want. How do specify in 'module1' which type Spring should instantiate?
You can use #Qualifier("some name") annotation.
There is more information about that: http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/
Spring eagerly instantiates singleton beans as stated in the documentation:
By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process.
which might explain why both #Components are created.
To specifiy which implementation is provided as a dependency you might want to check on Qualifiers that enable to choose between different implementations. In combination with lazy loading this should do the trick.
Depending on your personal taste you could also use delegation instead of inheritance using a separated interface:
public interface MyService {
public String foobar(int baz);
}
public static class CommonBehavior {
// whatever is used by Superclass and Subclass
}
#Component #Lazy
public class FormerSuperClass implements MyService {
private final CommonBehavior ...;
...
}
#Component #Lazy
public class FormerSubClass implements MyService {
private final CommonBehavior ...;
...
}
Good luck!
There are 2 methods: Use #Qualifier("SubclassName") Or Mark your subclass as #Component and declare the subclass when #Autowired
In your case:
Use #Qualifier("SubclassName")
#Component
public class Superclass {
// stuff
}
#component
public class Subclass extends Superclass {
// overridden stuff
}
public class AService {
#Autowired
#Qualifier("Subclass")
private Superclass superclass;
// service stuff
}
2.Mark your subclass as #Component and declare the subclass when #Autowired
public class Superclass {
// stuff
}
#component
public class Subclass extends Superclass {
// overridden stuff
}
public class AService {
#Autowired
private Subclass subclass;
// service stuff
}

Polymorphic EJB client

I am using EJB 3.1 and jersey for a restapi. I would like to have a SuperResource as below, which is then inherited by the actual rest resources as below. The way I have it now, my #EJB object is null. Does anyone know how to fix this?
#Stateless
public class SuperResource {
#EJB
protected GenericDao<DomainObject> dao;
. . .
}
public class MyResource extends SuperResource{
public String doGet(){
return dao.get(...);
}
}
I have tried the whole truth table between #Stateless and #Local, and SuperResource and MyResource. None of the permutations seems to work.
I don't know if that's important, my server is Glassfish 3.1.2
EDIT TO ADD DETAILS:
I didn't think so , but it seems that more detail may be necessary here:
Structure of my application:
#Local
public interface GenericDao<T extends DomainObject> {…}
public interface LoginDao extends GenericDao<Login>{...}
#Stateless
public class GenericDaoImpl<T extends DomainObject> implements GenericDao<T> {…}
#Stateless
public class LoginDaoImpl extends GenericDaoImpl<Login> implements LoginDao {…}
#Entity
public class Login implements java.io.Serializable, DomainObject {…}
What works:
#Stateless
#Path("mypath")
public class MyResource{  
#EJB
private LoginDao dao; 
public String doGet(){
return dao.get(...);
}
}
MyResource has to be an EJB bean as well, by annotating it with #Stateless:
#Stateless
public class MyResource extends SuperResource{
public String doGet(){
return dao.get(...);
}
}
If you only need the injected DAO, you could choose to inject your JAX-RS resource with that DAO using CDI instead. If you resources -becomes- a stateless bean, then this has certain consequences that you need to be aware of (like a transaction that starts for every method, unless you explicitly disable that, etc).
It looks like EJB injection issue. Depending on Server, you need to play around mappedName/name/beanName
What I can confirm is that, the following code works on JBoss 7.1.1.
#Local
public interface HelloWorldLocal {
public String sayHello();
}
#Stateless
public class HelloWorldBean implements HelloWorldLocal {
public String sayHello(){
return "Hello..............................................................................";
}
}
#Remote
public interface BaseRemote {
public String test();
}
#Stateless
public class BaseBean implements BaseRemote{
#EJB
HelloWorldLocal bean;
public String test() {
return "Base Bean";
}
}
#Remote
public interface DerivedRemote {
String test();
}
#Stateful
public class DerivedBean extends BaseBean implements DerivedRemote{
public String test() {
return bean.sayHello();
}
}

Categories