Spring autowire dependency defined in an abstract class - java

I have an abstract class "Command" with an #Autowired dependency and classes extending the abstract class. The dependency is not being injected. The abstract and concrete classes are annotated with #Component and are being scanned. It seems that the base(abstract) class is not spring managed. What needs to be done for it to be? Is there an annotation to define it as abstract? I don't want to define the bean in XML.
public abstract class Command {
#Autowired
private SecurityUtils securityUtils;
....
#Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
#Component
public class NoteCommand extends Command {
...
}
My mistake I apologize. The command classes are injected in my controllers and one of them (NoteCommand) out many was instantiated manually via "new". All is good.

This can be achieved with XML configuration(not sure about annotations). Read this http://docs.spring.io/spring-framework/docs/3.0.0.RC3/reference/html/ch03s07.html
Try this(add other config to child bean?)
<bean id = "command" class = "some.package.name.Command" abstract = "true">
<property name = "securityUtils" ref = "securityUtils"/>
</bean>
<bean id ="noteCommand" class = "some.package.name.NoteCommand" parent="commadn">
</bean>
cheers!

In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:
public abstract class EO {
#Autowired
protected SmsNotificationService smsNotificationService;
#Autowired
protected SendEmailService sendEmailService;
...
protected abstract void executeOperation(GenericMessage gMessage);
}
public final class OperationsExecutor {
public enum OperationsType {
ENROLL, CAMPAIGN
}
private OperationsExecutor() {
}
public static Object delegateOperation(OperationsType type, Object obj)
{
switch(type) {
case ENROLL:
if (obj == null) {
return new EnrollOperation();
}
return EnrollOperation.validateRequestParams(obj);
case CAMPAIGN:
if (obj == null) {
return new CampaignOperation();
}
return CampaignOperation.validateRequestParams(obj);
default:
throw new IllegalArgumentException("OperationsType not supported.");
}
}
}
#Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
#Override
public void executeOperation(GenericMessage genericMessage) {
LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
}
}
Initially to inject the dependencies in the abstract class I tried all stereotype annotations like #Component, #Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **#Configurable(dependencyCheck = true)** annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
I also tried these other references to find a solution:
http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
Using abstract factory with Spring framework
Spring Autowiring not working for Abstract classes
Inject spring dependency in abstract super class
Spring and Abstract class - injecting properties in abstract classes
Spring can you autowire inside an abstract class?
Please try using **#Configurable(dependencyCheck = true)** and update this post, I might try helping you if you face any problems.

Related

Factory returns Bean with EJB injected field Null

I've got a Factory class in Java with some methods which return some Java Bean. All of these Java Beans have some DAO object as fields which are injected with the annotation #EJB. However in every case these DAO are all Null, so I suppose I've a problem with EJB injection. I use WebLogic for deploy. Any suggestions to resolve the issue?
//Factory class
public class Factory extends AbstractFactory {
#Override
public InterfaceService getService() {
return new ClassBean();
}
}
//Bean class
#Stateless(mappedName = "ClassBean")
#LocalBean
public class ClassBean implements IBeanService {
#EJB(beanName = "ClassDAO")
private ClassDAO classDAO;
public List<String> getList() throws ExpectedModelException {
return classDAO.getStringList(); //this one throws NullPointerException
}
Never create Enterprise-Beans using new.
The creation, caching, deletion,... is done by the container.
You must declare ClassDao as #Stateless or #Singleton, ... and the container will create and find it, hopefully if the names are correct.
The Factory is not necessary.

How can I make a field which is generic field autowired with dynamic generate in Spring?

I defined some interfaces with generic, and I have some classes injected in Spring context as Beans, could I dynamic create a manager bean to manage them, and it could be autowired in fields without any Bean def code of this manager?
I have tried FactoryBean way to implement it, but not worked, it couldn't transmit generic class info and the FactoryBean bean couldn't transmit any changable arguments.
I have tried BeanFactory way to implement it, when I getBeansOfType, these objects created without autowired, not worked...
Now I have a finally method which I think it's not very smart that is using ImportBeanDefinitionRegistrar and ClassPathBeanDefinitionScanner to scan all classes, then insert the manager's beanDefinition.
I'll be very appreciate if you supply any method, Thank you very much !
I want to implement it like this:
public interface Strategy<E extends BaseEnum>
{
public E getType();
}
public interface LoginStrategy extends Strategy<LoginType>
{
public LoginStrategy getType();
}
#Strategy
public class ALoginStrategy implements LoginStrategy
{
public getType()
{
return LoginType.OTP;
}
}
#Strategy
public class BLoginStrategy implements LoginStrategy
{
#Autowired
private UserMapper;
public getType()
{
return LoginType.PASSWORD;
}
}
public LoginServiceImpl implements LoginService
{
#Autowired
private StrategyManage<LoginType, LoginStrategy> strategyManager;
}
I want the strategyManager in LoginServiceImpl which is marked Autowired could be auto generated.
I also have a other question. It may be easier to explain what I want.
I have a model convertor implements a ModelConvertor interface, TL is lowerModel's class, TU is upperModel's class.
now there is a bean include code like this:
#Autowired
private ModelConvertor<UserPO, UserDO> userConvertor;
normally Spring frame would throw a Exception with a "no such bean" message, so I want to make this field could auto inject a value like this:
#Autowired
private ModelConvertor<UserPO, UserDO> userConvertor[ = new DefaultModelConvertor(UserPO.class, UserDO.class)];
How can I do to solve these problems, thanks a lot again!
I have resolved this problem, scan specific packages and dynamic generate beans to put on context.

where to apply ApplicationContextAware

I have a Service class which is a spring bean and I want to use this Service class inside a class (Class A) which is not a spring bean.
Where exactly should I implement ApplicationContextAware ?
Following is my code
#Service("sharedListsService")
public class SharedListsService
{
}
public class A
{
// I want to call my service class methods here
}
I'm not sure that it is a best solution but you can refactor your A class like following:
public class A {
private SharedListsService sharedListsService;
public void setSharedListsService(SharedListsService sharedListsService) {
this.sharedListsService = sharedListsService;
}
}
and then inject spring bean when you create an A class instance (for example):
SharedListsService sharedListsService = WebApplicationContextUtils.getWebApplicationContext(appContext).getBean(SharedListsService.class);
A a = new A();
a.setSharedListsService(sharedListsService);
ApplicationContextAware applies to spring beans only.
It will inject application context into a bean. That's why you cannot directly use it to get instance of SharedListsService into "A".
You need a bean, possibly a factory for "A" to wire that for you.

How can I generate/create new spring beans at runtime with a bean definition object?

I am new to Spring, and I would like to write a beanGenerator for a template bean. I would like to use this generator to overcome thread-safe concerns. Can anyone help me to add / modify the code to make this work? It's kind of hard to describe my real issue, so I abstract the issue in the following code:
abstract class BeanDefinition {
abstract public void preprocess();
}
// now we have 1st user specific bean :
class UserSpecifiedBeanDefinition extends BeanDefinition{
#override
public void preprocess() {
// do something
}
}
// we could have more user-specific beans that extend BeanDefinition
....
// Following generator class is used to generate beans
public class BeanGenerator {
private BeanDefinition beanDefinition;
public BeanGenerator(BeanDefinition beanDefinition) {
this.beanDefinition = beanDefinition;
}
public generate() {
BeanDefinition newBean = // create new bean based on beanDefinition? how can I make this work??
newBean.preprocess();
return newBean;
}
}
// In spring.xml, I would like to use them like:
<bean id="generator1" class="com.xxx.xxx.BeanGenerator">
<constructor-arg name="beanDefinition" ref="userSpecifiedBeanDefinition"/>
</bean>
I suppose you have a constructor without parameters. Use reflection to instantiate class
Class c = BeanGenerator.class.getClassLoader().loadClass(beanDefinition.getBeanClassName());
Constructor con = c.getConstructor();
Object instance = con.newInstance();
If you have constructor with parameters the logic should be changed to select correct constructor and pass the parameters to the newInstance() call

Assign data member of a domain class using Spring

Is it possible?
Here is a more detailed case:
class A {
private service x;
//other members
//some more methods.
}
bean definition is available for service but I do not want class A to be a spring bean and neither x to be static.
Is this achievable.
EDIT:
My spring configuration:
<bean id="Service" class="com.xx.yy.Service" />
<--!I do not register class A as a bean. Hence cannot use #autowired directly.-->
It can only be achieved by manually getting the bean from the context.
Service service = context.getBean(Service.class);
A a = new A(service);
I think you should create the factory for instances of class A which should take care of setting x.
#Service
class FactoryA {
#Autowired service x;
public A create() {
return new A(x);
}
}

Categories

Resources