Custom field uniqness validation for classes implementing common interface Hibernate + Spring - java

I'm trying to make a custom validation (checking if an email is already present in the database). For single class my annotation is working fine but I need to make this validation work for two objects implementing common interface. I have User interface and Visitor and Exhibitor classes which are implementing it.
Here is my annotation:
#Documented
#Constraint(validatedBy = UniqueEmailValidator.class)
#Target({ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface UniqueEmail {
String message() default "Email is already existing!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Here is Validator class
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
#Autowired
private ApplicationContext applicationContext;
private UserService userService;
#Override
public void initialize(UniqueEmail uniqueEmail) {
}
#Override
public boolean isValid(String email, ConstraintValidatorContext constraintValidatorContext) {
return !userService.isEmailPresent(email);
}
}
UserService is a common interface of VisitorService and ExhibitorService
public interface UserService {
boolean isEmailPresent(String email);
}
And it's implementation...
#Service
public class VisitorService implements UserService {
#Autowired
VisitorDao visitorDao;
#Override
public boolean isEmailPresent(String email) {
try {
return !visitorDao.findAllByEmail(email).isEmpty();
} catch (NullPointerException e) {
return false;
}
}
}
Currently I'm getting NullPointerException
java.lang.NullPointerException: null
at pl.com.sremski.testapp.validators.UniqueEmailValidator.isValid(UniqueEmailValidator.java:24) ~[classes/:na]
at pl.com.sremski.testapp.validators.UniqueEmailValidator.isValid(UniqueEmailValidator.java:10)
Any ideas what's the reason? I was trying to debug and UserService is null... but I'm trying to add a new visitor so it should use VisitorService. Please help.

I managed to solve my problem by specifing exact implementation in annotation's parameter
#UniqueEmail(service = VisitorService.class)
and then creating it's instance in
#Override
public void initialize(UniqueEmail uniqueEmail) {
}
However I had to separate all Spring-based validation from Hibernate's entity to make it work.

If you don't want to have two different annotations with different #Qualifier() marked beans, you can consider to choose that bean in runtime using application context. But injecting whole Spring context to your business logic is considered as a very bad practice:
1) Mixing infrastructure (your WHOLE infrastructure) with business processes makes your code hard to understand and decouple.
2) It is hard to unit test this, need to mock the context object instead of your services.
But after using Google Guice DI I found myself in using Provider<Service> pattern, because injecting spring into spring is OK. So you can create a class like:
#Service
class UserServiceProvider<T extends UserService> implements Provider<T> {
#Autowired private ApplicationContext context;
public UserService get(Class<T> exactServiceType) {
return (UserService) context.getBean(exactServiceType);
}
}
Maybe there is a much better "Spring way" to do this, but this code is easy to understand and maintain. Works lile a Scope.Prototype bean, but a bit more flexible.
Google Guice Provider tutorial
EDIT:
Spring has a similar interface FactoryBean<T> and it has an enhanced handling, because DI will inject not the factory, but what factory provides.
But the one problem is you can't do it with some condition.
Simple example

Related

Inject spring bean dynamically

In a java-spring web-app I would like to be able to dynamically inject beans.
For example I have an interface with 2 different implementations:
In my app I'm using some properties file to configure injections:
#Determines the interface type the app uses. Possible values: implA, implB
myinterface.type=implA
My injections actually loaded conditionally relaying on the properties values in the properties file. For example in this case myinterface.type=implA wherever I inject MyInterface the implementation that will be injected will be ImplA (I accomplished that by extending the Conditional annotation).
I would like that during runtime - once the properties are changed the following will happen (without server restart):
The right implementation will be injected. For example when setting myinterface.type=implB ImplB will be injected where-ever MyInterface is used
Spring Environment should be refreshed with the new values and re-injected as well to beans.
I thought of refreshing my context but that creates problems.
I thought maybe to use setters for injection and re-use those setters once properties are re-configured. Is there a working practice for such a requirement?
Any ideas?
UPDATE
As some suggested I can use a factory/registry that holds both implementations (ImplA and ImplB) and returns the right one by querying the relevant property.
If I do that I still have the second challenge - the environment. for example if my registry looks like this:
#Service
public class MyRegistry {
private String configurationValue;
private final MyInterface implA;
private final MyInterface implB;
#Inject
public MyRegistry(Environmant env, MyInterface implA, MyInterface ImplB) {
this.implA = implA;
this.implB = implB;
this.configurationValue = env.getProperty("myinterface.type");
}
public MyInterface getMyInterface() {
switch(configurationValue) {
case "implA":
return implA;
case "implB":
return implB;
}
}
}
Once property has changed I should re-inject my environment. any suggestions for that?
I know I can query that env inside the method instead of constructor but this is a performance reduction and also I would like to think of an ider for re-injecting environment (again, maybe using a setter injection?).
I would keep this task as simple as possible. Instead of conditionally load one implementation of the MyInterface interface at startup and then fire an event that triggers dynamic loading of another implementation of the same interface, I would tackle this problem in a different way, that is much simpler to implement and maintain.
First of all, I'd just load all possible implementations:
#Component
public class MyInterfaceImplementationsHolder {
#Autowired
private Map<String, MyInterface> implementations;
public MyInterface get(String impl) {
return this.implementations.get(impl);
}
}
This bean is just a holder for all implementations of the MyInterface interface. Nothing magic here, just common Spring autowiring behavior.
Now, wherever you need to inject a specific implementation of MyInterface, you could do it with the help of an interface:
public interface MyInterfaceReloader {
void changeImplementation(MyInterface impl);
}
Then, for every class that needs to be notified of a change of the implementation, just make it implement the MyInterfaceReloader interface. For instance:
#Component
public class SomeBean implements MyInterfaceReloader {
// Do not autowire
private MyInterface myInterface;
#Override
public void changeImplementation(MyInterface impl) {
this.myInterface = impl;
}
}
Finally, you need a bean that actually changes the implementation in every bean that has MyInterface as an attribute:
#Component
public class MyInterfaceImplementationUpdater {
#Autowired
private Map<String, MyInterfaceReloader> reloaders;
#Autowired
private MyInterfaceImplementationsHolder holder;
public void updateImplementations(String implBeanName) {
this.reloaders.forEach((k, v) ->
v.changeImplementation(this.holder.get(implBeanName)));
}
}
This simply autowires all beans that implement the MyInterfaceReloader interface and updates each one of them with the new implementation, which is retrieved from the holder and passed as an argument. Again, common Spring autowiring rules.
Whenever you want the implementation to be changed, you should just invoke the updateImplementations method with the name of the bean of the new implementation, which is the lower camel case simple name of the class, i.e. myImplA or myImplB for classes MyImplA and MyImplB.
You should also invoke this method at startup, so that an initial implementation is set on every bean that implements the MyInterfaceReloader interface.
I solved a similar issue by using org.apache.commons.configuration.PropertiesConfiguration and org.springframework.beans.factory.config.ServiceLocatorFactoryBean:
Let VehicleRepairService be an interface:
public interface VehicleRepairService {
void repair();
}
and CarRepairService and TruckRepairService two classes that implements it:
public class CarRepairService implements VehicleRepairService {
#Override
public void repair() {
System.out.println("repair a car");
}
}
public class TruckRepairService implements VehicleRepairService {
#Override
public void repair() {
System.out.println("repair a truck");
}
}
I create an interface for a service factory:
public interface VehicleRepairServiceFactory {
VehicleRepairService getRepairService(String serviceType);
}
Let use Config as configuration class:
#Configuration()
#ComponentScan(basePackages = "config.test")
public class Config {
#Bean
public PropertiesConfiguration configuration(){
try {
PropertiesConfiguration configuration = new PropertiesConfiguration("example.properties");
configuration
.setReloadingStrategy(new FileChangedReloadingStrategy());
return configuration;
} catch (ConfigurationException e) {
throw new IllegalStateException(e);
}
}
#Bean
public ServiceLocatorFactoryBean serviceLocatorFactoryBean() {
ServiceLocatorFactoryBean serviceLocatorFactoryBean = new ServiceLocatorFactoryBean();
serviceLocatorFactoryBean
.setServiceLocatorInterface(VehicleRepairServiceFactory.class);
return serviceLocatorFactoryBean;
}
#Bean
public CarRepairService carRepairService() {
return new CarRepairService();
}
#Bean
public TruckRepairService truckRepairService() {
return new TruckRepairService();
}
#Bean
public SomeService someService(){
return new SomeService();
}
}
By using FileChangedReloadingStrategy your configuration be reload when you change the property file.
service=truckRepairService
#service=carRepairService
Having the configuration and the factory in your service, let you can get the appropriate service from the factory using the current value of the property.
#Service
public class SomeService {
#Autowired
private VehicleRepairServiceFactory factory;
#Autowired
private PropertiesConfiguration configuration;
public void doSomething() {
String service = configuration.getString("service");
VehicleRepairService vehicleRepairService = factory.getRepairService(service);
vehicleRepairService.repair();
}
}
Hope it helps.
If I understand you correctly then the goal is not to replace injected object instances but to use different implementations during interface method call depends on some condition at run time.
If it is so then you can try to look at the Sring TargetSource mechanism in combination with ProxyFactoryBean. The point is that proxy objects will be injected to beans that uses your interface, and all the interface method calls will be sent to TargetSource target.
Let's call this "Polymorphic Proxy".
Have a look at example below:
ConditionalTargetSource.java
#Component
public class ConditionalTargetSource implements TargetSource {
#Autowired
private MyRegistry registry;
#Override
public Class<?> getTargetClass() {
return MyInterface.class;
}
#Override
public boolean isStatic() {
return false;
}
#Override
public Object getTarget() throws Exception {
return registry.getMyInterface();
}
#Override
public void releaseTarget(Object target) throws Exception {
//Do some staff here if you want to release something related to interface instances that was created with MyRegistry.
}
}
applicationContext.xml
<bean id="myInterfaceFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="MyInterface"/>
<property name="targetSource" ref="conditionalTargetSource"/>
</bean>
<bean name="conditionalTargetSource" class="ConditionalTargetSource"/>
SomeService.java
#Service
public class SomeService {
#Autowired
private MyInterface myInterfaceBean;
public void foo(){
//Here we have `myInterfaceBean` proxy that will do `conditionalTargetSource.getTarget().bar()`
myInterfaceBean.bar();
}
}
Also if you want to have both MyInterface implementations to be Spring beans, and the Spring context could not contains both instances at the same time then you can try to use ServiceLocatorFactoryBean with prototype target beans scope and Conditional annotation on target implementation classes. This approach can be used instead of MyRegistry.
P.S.
Probably Application Context refresh operation also can do what you want but it can cause other problems such as performance overheads.
This may be a duplicate question or at least very similar, anyway I answered this sort of question here: Spring bean partial autowire prototype constructor
Pretty much when you want a different beans for a dependency at run-time you need to use a prototype scope. Then you can use a configuration to return different implementations of the prototype bean. You will need to handle the logic on which implementation to return yourself, (they could even be returning 2 different singleton beans it doesn't matter) But say you want new beans, and the logic for returning the implementation is in a bean called SomeBeanWithLogic.isSomeBooleanExpression(), then you can make a configuration:
#Configuration
public class SpringConfiguration
{
#Bean
#Autowired
#Scope("prototype")
public MyInterface createBean(SomeBeanWithLogic someBeanWithLogic )
{
if (someBeanWithLogic .isSomeBooleanExpression())
{
return new ImplA(); // I could be a singleton bean
}
else
{
return new ImplB(); // I could also be a singleton bean
}
}
}
There should never be a need to reload the context. If for instance, you want the implementation of a bean to change at run-time, use the above. If you really need to reload your application, because this bean was used in constructors of a singleton bean or something weird, then you need to re-think your design, and if these beans are really singleton beans. You shouldn't be reloading the context to re-create singleton beans to achieve different run-time behavior, that is not needed.
Edit The first part of this answer answered the question about dynamically injecting beans. As asked, but I think the question is more of one: 'how can I change the implementation of a singleton bean at run-time'. This could be done with a proxy design pattern.
interface MyInterface
{
public String doStuff();
}
#Component
public class Bean implements MyInterface
{
boolean todo = false; // change me as needed
// autowire implementations or create instances within this class as needed
#Qualifier("implA")
#Autowired
MyInterface implA;
#Qualifier("implB")
#Autowired
MyInterface implB;
public String doStuff()
{
if (todo)
{
return implA.doStuff();
}
else
{
return implB.doStuff();
}
}
}
You can use #Resource annotation for injection as originally answered here
e.g.
#Component("implA")
public class ImplA implements MyInterface {
...
}
#Component("implB")
public class ImplB implements MyInterface {
...
}
#Component
public class DependentClass {
#Resource(name = "\${myinterface.type}")
private MyInterface impl;
}
and then set the implementation type in properties file as -
myinterface.type=implA
Be aware that - if interesting to know about - FileChangedReloadingStrategy makes your project highly dependent on the deployment conditions: the WAR/EAR should be exploded by container and your should have direct access to the file system, conditions that are not always met in all situations and environments.
You can use Spring #Conditional on a property value. Give both Beans the same name and it should work as only one Instance will be created.
Have a look here on how to use #Conditional on Services and Components:
http://blog.codeleak.pl/2015/11/how-to-register-components-using.html
public abstract class SystemService {
}
public class FooSystemService extends FileSystemService {
}
public class GoSystemService extends FileSystemService {
}
#Configuration
public class SystemServiceConf {
#Bean
#Conditional(SystemServiceCondition.class)
public SystemService systemService(#Value("${value.key}") value) {
switch (value) {
case A:
return new FooSystemService();
case B:
return new GoSystemService();
default:
throw new RuntimeException("unknown value ");
}
}
}
public class SystemServiceCondition implements Condition {
#Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return true;
}
}

How to use a dynamic implementation of an interface in Spring?

This question is intended to make an answer for a useful issue.
Suppose we have a Spring application with a #Controller, an interface and different implementations of that interface.
We want that the #Controller use the interface with the proper implementation, based on the request that we receive.
Here is the #Controller:
#Controller
public class SampleController {
#RequestMapping(path = "/path/{service}", method = RequestMethod.GET)
public void method(#PathVariable("service") String service){
// here we have to use the right implementation of the interface
}
}
Here is the interface:
public interface SampleInterface {
public void sampleMethod(); // a sample method
}
Here is one of the possibile implementation:
public class SampleInterfaceImpl implements SampleInterface {
public void sampleMethod() {
// ...
}
}
And here is another one:
Here is one of the possibile implementation:
public class SampleInterfaceOtherImpl implements SampleInterface {
public void sampleMethod() {
// ...
}
}
Below I'll show the solution that I've found to use one of the implementations dynamically based on the request.
The solution I've found is this one.
First, we have to autowire the ApplicationContext in the #Controller.
#Autowired
private ApplicationContext appContext;
Second, we have to use the #Service annotation in the implementations of the interface.
In the example, I give them the names "Basic" and "Other".
#Service("Basic")
public class SampleInterfaceImpl implements SampleInterface {
public void sampleMethod() {
// ...
}
}
#Service("Other")
public class SampleInterfaceOtherImpl implements SampleInterface {
public void sampleMethod() {
// ...
}
}
Next, we have to obtain the implementation in the #Controller.
Here's one possible way:
#Controller
public class SampleController {
#Autowired
private ApplicationContext appContext;
#RequestMapping(path = "/path/{service}", method = RequestMethod.GET)
public void method(#PathVariable("service") String service){
SampleInterface sample = appContext.getBean(service, SampleInterface.class);
sample.sampleMethod();
}
}
In this way, Spring injects the right bean in a dynamic context, so the interface is resolved with the properly inmplementation.
I solved that problem like this:
Let the interface implement a method supports(...) and inject a List<SampleInterface> into your controller.
create a method getCurrentImpl(...) in the controller to resolve it with the help of supports
since Spring 4 the autowired list will be ordered if you implement the Ordered interface or use the annotation #Order.
This way you have no need for using the ApplicationContext explicitly.
Honestly I don't think the idea of exposing internal implementation details in the URL just to avoid writing some lines of code is good.
The solution proposed by #kriger at least adds one indirection step using a key / value approach.
I would prefer to create a Factory Bean (to be even more enterprise oriented even an Abstract Factory Pattern) that will choose which concrete implementation to use.
In this way you will be able to choose the interface in a separate place (the factory method) using any custom logic you wish.
And you will be able to decouple the service URL from the concrete implementation (which is not very safe).
If you are creating a very simple service your solution will work, but in an enterprise environment the use of patterns is vital to ensure maintenability and scalability.
I'm not convinced with your solution because there's an implicit link between an HTTP parameter value and a bean qualifier. Innocent change of the bean name would result in a disaster that could be tricky to debug. I would encapsulate all the necessary information in one place to ensure any changes only need to be done in a single bean:
#Controller
public class SampleController {
#Autowired
private SampleInterfaceImpl basic;
#Autowired
private SampleInterfaceOtherImpl other;
Map<String, SampleInterface> services;
#PostConstruct
void init() {
services = new HashMap()<>;
services.put("Basic", basic);
services.put("Other", other);
}
#RequestMapping(path = "/path/{service}", method = RequestMethod.GET)
public void method(#PathVariable("service") String service){
SampleInterface sample = services.get(service);
// remember to handle the case where there's no corresponding service
sample.sampleMethod();
}
}
Also, dependency on the ApplicationContext object will make it more complicated to test.
NB. to make it more robust I'd use enums instead of the "Basic" and "Other" strings.
However, if you know you'll only have two types of the service to choose from, this would be the "keep it simple stupid" way:
#Controller
public class SampleController {
#Autowired
private SampleInterfaceImpl basic;
#Autowired
private SampleInterfaceOtherImpl other;
#RequestMapping(path = "/path/Basic", method = RequestMethod.GET)
public void basic() {
basic.sampleMethod();
}
#RequestMapping(path = "/path/Other", method = RequestMethod.GET)
public void other() {
other.sampleMethod();
}
}

How to provide a default bean in Spring by condition?

I'd like to provide a default bean by a custom jar. Only if the user implements a specific abstract class the default bean injection should be skipped.
The following setup already works fine, except one thing: any injected classes within the default wired class are null! What might I be missing?
#Configration
public class AppConfig {
//use the default service if the user does not provide an own implementation
#Bean
#Conditional(MissingServiceBean.class)
public MyService myService() {
return new MyService() {};
}
}
#Component
public abstract class MyService {
#Autowired
private SomeOtherService other;
//default impl of the method, that may be overridden
public void run() {
System.out.println(other); //null! Why?
}
}
public class MissingServiceBean implements Condition {
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getBeanFactory().getBeansOfType(MyService.class).isEmpty();
}
}
The MyService bean is created and can also be injected. But contained classes are null.
If I remove the #Conditioanl annotation everything works as expected.
Your simplest possibility is the usage of the #Primary annotation. You define your interface/abstract class and build a default implementation. Until here thats the basic spring autowiring.
Now you create another implementation with #Primary and make it available in the application context. Spring will now pick up the primary implementation for the autowiring.
Another possibilty in Spring 4.1+ would be to autowire an ordered List<Intf> and ask the interface with a supports(...) call to fetch the current implementation for whatever parameter you give into supports. You give the default implementation a low priority and the more detailed ones a higher priority. Like this you can even build a more detailed default behavior. I'm using this approach for several configurations to handle different classes with default and specific implementations.
One example would be during permission evaluation where we have a default config for the base classes, another higher one for domain classes, and a even higher possible one for specific domain entities. The permission evaluator goes through the list and checks each implementation if it supports that class and delegates to the implementation in that case.
I dont have the code here but i could share it later if desired to make that more clear.
Change your code to the following:
public abstract class MyService {
private final SomeOtherService other;
public MyService(SomeOtherService other) {
this.other = other;
}
//default impl of the method, that may be overridden
public void run() {
System.out.println(other);
}
}
#Configration
public class AppConfig {
#Autowired
private SomeOtherService other;
//use the default service if the user does not provide an own implementation
#Bean
#Condition(MissingServiceBean.class)
public MyService myService() {
return new MyService(other) {};
}
}

Using #Autowired component in custom JSR-303 validator

I'm trying to implement a custom validator for my model classes that autowires a custom bean of mine (declared via #Component).
In this, I followed the Spring documentation on that topic. My AuthenticationFacade object is implemented according to this tutorial.
When running my tests, however, the autowired attribute in the Validator object is always null. Why is that?
Here are the relevant parts of my code:
My custom bean, AuthenticationFacadeImpl.java
#Component
public class AuthenticationFacadeImpl implements AuthenticationFacade {
boolean hasAnyRole(Collection<String> roles) {
// checks currently logged in user roles
}
}
My custom constraint, HasAnyRoleConstraint.java
#Constraint(validatedBy = HasAnyRoleConstraintValidator.class)
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD})
public #interface HasAnyRole {
String[] value();
String message() default "{HasAnyRole}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
My custom validator, HasAnyRoleConstraintValidator.java
#Component
public class HasAnyRoleConstraintValidator implements ConstraintValidator<HasAnyRole, Object> {
#Autowired
AuthenticationFacade authenticationFacade;
private String[] roles;
#Override
public void initialize(HasAnyRole hasAnyRole) {
this.roles = hasAnyRole.value();
}
#Override
public boolean isValid(Object target, ConstraintValidatorContext constraintValidatorContext) {
return target == null || authenticationFacade.hasAnyRole(Arrays.asList(this.roles));
}
}
The model class, Article.java
#Entity
public class Article {
// ...
#HasAnyRole({"EDITOR", "ADMIN"})
private String title;
// ...
}
The service object, ArticleServiceImpl.java
#Service
public class ArticleServiceImpl implements ArticleService {
#Autowired
private ArticleRepository articleRepository;
#Autowired
private AuthenticationFacade authenticationFacade;
#Autowired
private Validator validator;
#Override
#PreAuthorize("hasAnyRole('ADMIN', 'EDITOR')")
public boolean createArticle(Article article, Errors errors) {
articleRepository.save(article);
return true;
}
The Errors object that gets fed into the createArticle method is intended to come from the Spring controller, which gets fed a model object with the #Valid annotation.
The repository, ArticleRepository.java, uses Spring Data JPA's JpaRepository
public interface ArticleRepository extends JpaRepository<Article, Long> {
}
I solved this for now by ditching Dependency Injection for the Validator class, instead instantiating an instance of AuthenticationFacadeImpl in the constructor.
Would still be interesting, though how to combine the use of #Valid in the Controllers with custom validators + #Autowired attributes in the Model without explicitely calling the Validator in the code...
If your validator is instantiated outside the Spring context, then you can use Spring’s AOP #Configurable magic to register it in context and get autowiring work. All what you need is to annotate HasAnyRoleConstraintValidator with #Configurable and enable compile time, or load time aspects weaving.

Reflection + spring dependency injection

I'm trying to understand if I can combine reflection with spring dependency injection as the following:
public interface ClientCommand {
public void execute(...);
public static enum Command {
SomeCommand(SomeCommand.class);
private Class<? extends ClientCommand> clazz;
private Command(Class<? extends ClientCommand> clazz) {
this.clazz = clazz;
}
public Class<? extends ClientCommand> getClazz() {
return clazz;
}
public static ClientCommand getClientCommand(String name) {
Command command = Enum.valueOf(Command.class, name);
return command.getClazz().newInstance();
}
}
}
This will create an instance of a command class based on the name passed in getClientCommand.
This is an example of class extending ClientCommand:
public class LoginCommand implements ClientCommand {
#Autowired
private UserRepository userRepository;
public void setUserRepository(#Qualifier("userRepository")UserRepository userRepository) {
this.userRepository = userRepository;
}
public void execute(...) {
...
}
}
And the repository is something like:
#Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
....
}
When the LoginCommand.execute() method is executed, the UserRepository is null.
If I use the newInstance() to create the object, does spring care at all to inject the dependencies?
More than for practical use, is to understand if is theoretically possible to get this code working.
Thanks in advance
To answer this question:
If I use the newInstance() to create the object, does spring care at all to inject the dependencies?
I will answer with no, not by default. Spring will only inject dependencies on objects that Spring is in control of, and if you are using reflection to instantiate it, or the new operator, then you are the one in control, not Spring.
But, there is hope. You can use AspectJ to do bytecode weaving when the new operator is used, or even when Class.newInstance() is used.
Take a look at this Spring documentation for more on this approach.
Since you're creating the object on your own Spring will not do dependency injection on the object. It will also not add any AOP proxies for it if its configured to do that.
You can either use AspectJ to instrument your code by adding the logic necessary to do dependency injection on the instance. This is done completely transparently.
Or you can do it yourself by using AutowireCapableBeanFactory. It's a semi-internal interface that you can use and its intended for just this purpose. It has a set of methods that do various parts of creating and injecting, you'll probably need the createBean() method.
You can get an AutowireCapableBeanFactory by calling getAutowireCapableBeanFactory on your ApplicationContext.
In your case it would probably be a good idea to create a CommandFactory, make that implement ApplicationContextAware and have a method like createCommand() that calls createBean().

Categories