Does Groovy respect #PostConstruct? - java

Consider a bit of Groovy code like:
def trainingCorpus = new CorpusNexmlReader(ignoreMissingTags: true,
model: model, source: corpus,
abideByUse: true, useListSource: true,
listSourceDir: corpus + "/all/",
listSource: corpus + "/all/split_all.txt",
tagMap: tagMap
)
This helpfully uses the no-args constructor to make the object, and then makes calls
to all the setters corresponding to the named parameters. Now, if I add an #PostConstruct,
will Groovy call it after all those setters?

No, it won't. The #PostConstruct is used only for spring beans (instantiated by the spring context, and not by you)

From the javadocs on the #PostConstruct annotation:
"The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection"
Groovy is not a dependency injection framework. It will not do any processing of annotations directed toward DI frameworks. If you were building your bean as a Spring bean using Groovy's spring builder, then it should respect that annotation.
Alternately, you could read and process that annotation yourself.

Related

Using Spring bean vs a static instance pattern for Mapstruct

I know that you can use the annotation #Mapper(componentModel = “spring”) to use Spring to manage/inject the mapper dependency. My question is, are there any advantages to this approach vs declaring an instance variable within the mapper class itself:
#Mapper
public interface SomeMapper {
SomeMapper INSTANCE = Mappers.getMapper(SomeMapper.class);
SomethingElse mapSomethingToSomethingElse(Something something);
}
...
// Clients using mapper
SomethingElse result = SomeMapper.INSTANCE.mapSomethingToSomethingElse(input);
When using Spring dependency injection to inject mappers, you will end up adding extra constructor arguments/instance fields which is desirable as it makes it more obvious that a class is starting to rely on too many dependencies and should most likely be refactored (eg. think about Sonar's rule 'Too many parameters').
Another advantage is that since you're registering the mappers as beans in the Spring context, you can leverage the framework capabilities to easily inject dependencies in your mappers, customize all mappers at runtime through the BeanFactoryPostProcessor and rely on all the other framework abstractions that seem fit.
I'd say since you're already using Spring in your application, there is pretty much no reason to not register the mappers as Spring beans and inject them the DI way rather than turning them into static utils.

Constructor bean injection with custom annotation

I would like to inject a bean (lets call it clientStub) into my service bean.
There are two requirements for that:
In order to create the clientStub bean, I need to access the #Client annotation, that carries some important information that are used to lookup the relevant configuration in the properties.
It must support constructor based injection (and #Bean method parameter injection)
Expected usage:
#Autowired
public MyService(
#Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
or
#Bean
MyService myService(
#Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
So I would like to do the same as the #Value annotation e.g. derive the value from the annotation on the parameter (plus some internal lookups).
Unfortunately, the usual BeanFactorys don't seem to be aware of the target's annotations.
Alternatives considered
Using an BeanPostProcessor to inject the values into annotated fields. Well, this is what I'm currently doing, but it doesn't feel right to have an immutable class with a single setter for injection.
Injecting it to a field and then exposing it as a bean or manually invoking the constructor is even worse.
Creating a proxy instance of the injected class. This isn't possible since the injected classes are generated + final and not part of my library.
Derive the configuration from the bean name: Not sure how to implement this and how to explain the user what the configuration parameters should be named in their properties files. I also would like to avoid bean name conflicts.
Non-Goals
Overwriting any core beans. I would like to distribute the extension as a library (spring-boot based), so any excessive replacement of spring internal beans should be avoided.
TLDR
How do I tell spring to resolve the parameter using my annotation's value (resolver)?

What is javax.inject.Named annotation supposed to be used for?

I am trying to understand the javax.inject package and I am not clear what the javax.inject.Named annotation is supposed to be used for. The Javadoc does not explain the the idea behind it.
Javadoc is at http://download.oracle.com/javaee/6/api/javax/inject/Named.html
I am using Spring 3.0 to write some sample programs, by putting #Named on a bean it seems to add it to the bean factory but the Javadoc description is so light I can't tell if that is the standard behavior or Spring specific behavior.
My questions are:
What is the difference between #Named and #Qualifier
How are you supposed to tell the Runtime system a class should be injectable in other classes what's the annotation for that? The equivalent of #Component in Spring?
Update 1 there is an excellent explanation of #Named and #Qualifier at Nice article about #Named and #Qualifier https://dzone.com/articles/java-ee6-cdi-named-components thanks #xmedeko for linking to it the comment below.
Use #Named to differentiate between different objects of the same type bound in the same scope.
#Named("maxWaitTime")
public long maxWaitTimeMs;
#Named("minWaitTime")
public long minWaitTimeMs;
Without the #Named qualifier, the injector would not know which long to bind to which variable.
If you want to create annotations that act like #Named, use the #Qualifier annotation when creating them.
If you look at #Named, it is itself annotated with #Qualifier.
#Inject instead of Spring’s #Autowired to inject a bean.
#Named instead of Spring’s #Component to declare a bean.
Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotation (as long as the following jar is in your classpath)
Regarding #2, according to the JSR-330 spec:
This package provides dependency
injection annotations that enable
portable classes, but it leaves
external dependency configuration up
to the injector implementation.
So it's up to the provider to determine which objects are available for injection. In the case of Spring it is all Spring beans. And any class annotated with JSR-330 annotations are automatically added as Spring beans when using an AnnotationConfigApplicationContext.
The primary role of the #Named annotation is to define a bean for the purpose of resolving EL statements within the application, usually through JSF EL resolvers. Injection can be performed using names but this was not how injection in CDI was meant to work since CDI gives us a much richer way to express injection points and the beans to be injected into them.

Method Parameter Validation with JSR-303

Is JSR-303 also intended for method parameter validation?
If so, is there any example on the web? The biggest challenge I'm facing is how to get a validator within each method. With Spring 3, doesn't it mean that I'd have to inject virtually every class with a LocalValidatorFactoryBean?
Thanks!
Method level validation will be supported in the upcoming version 4.2 of JSR 303's reference implementation Hibernate Validator.
As pointed out in the previous answer this will allow constraint annotations (built-in as well as custom defined types) to be specified at method parameters and return values to specify pre- and post-conditions for a method's invocation.
Note that HV will only deal with the actual validation of method calls not with triggering such a validation. Validation invocation could be done using AOP or other method interception facilities such as JDK's dynamic proxies.
The JIRA issue for this is HV-347 [1], so you might want to add yourself as watcher to this issue.
[1] http://opensource.atlassian.com/projects/hibernate/browse/HV-347
The javadocs for each of the JSR 303 annotations tells the following:
#Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
See, PARAMETER is there. So, yes, it's technically possible.
Here's an example:
public void method(#NotNull String parameter) {
// ...
}
I'm however not sure how that integrates with Spring since I don't use it. You could just give it a try.
In Spring 3.1.0 you can use #Validated annotation to activate validation on a pojo.
Create an interface for the pojo class an put this annotation over it, then add your validation annotations in the methods definitions. ( the interface is required because Spring will create a proxy class using the interface as definition )
#Validated
public interface PojoClass {
public #NotNull String doSomething(#NotEmpty String input);
}
your pojo :
public class PojoClassImpl implements PojoClass {
public String doSomething(String input) {
return "";
}
}
Starting from a standard spring web application with active validation, remember to add in your spring configuration this bean declaration:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
This sounds like a use case for AOP (AspectJ). Write a pointcut for methods that are annotated with javax.validation.constraints.*, inject a validator into the aspect (probably using Spring) and use a #Before or #Around advice to perform the validation before method execution.
Read AspectJ in Action for reference.
You can use jcabi-aspects (I'm a developer), which integrates JSR 303 with AspectJ. Actual validation is done by one of JSR 303 implementations, which you will have to add to class path, like Hibernate Validator, or Apache BVal.

Specifying Group for Bean Validation with SimpleFormController

I'm working with an older spring project that's using the SimpleFormController. It was easy to switch in the beanvalidation.LocalValidatorFactoryBean validator bean to look at the annotations on the command object, but I can't see how I would override one of the methods to enable the validator to look at a specified group of validation rules. Any ideas?
You could conceivably write a spring Validator which thinly wraps the javax.validation.Validator, which would allow you to call the rules you would like; and just inject this into the controller.

Categories