Spring Configuration bean not eligible for getting processed by BeanPostProcessors - spring

I am building a multi module Spring Boot project, which will implement Spring’s SOAP Web Services.
One of the classes is as follows:
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
#Configuration
public class MyWebServiceConfig extends WsConfigurerAdapter{
…
}
The following message is logged immediately after application startup
Bean “myWebServiceConfig of type [com.mycompany.MyWebServiceConfig$$EnhancerBySpringCGLIB$$6c32dec5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
(For simplicity, am not including the beans within the configuration class which are required as part of Spring's SOAP endpoint configuration. Nor am I including the #EnableWS annotation. The same message is logged with or without these).
If there is no auto proxying, nothing is going to work.
I have tried annotating the class with #Lazy and Order(Ordered.LOWEST_PRECEDENCE), but these do not help.
While I have seen others with the same issue resolve it using DependsOn, I do not know how that would work here.
Apart from those provided by Spring, there are no classes I am aware of within the application which implement BeanPostProcessor.
Furthermore, if MyWebServiceConfig is deleted, the same message is displayed about the following class:
com.springframework.ws.config.annotation.DelegatingWebServiceConfiguration
which lives in spring-ws-core-3.1.3.jar
and I obviously have no control over.
This jar is a transient dependency of:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
<version>2.7.1</version>
</dependency>
Debugging, this message which appears on startup is logged in the following class:
PostProcessorRegistrationDelegate.
This has an inner class, BeanPostProcessorChecker
which includes the following method:
public Object postProcessAfterInitialization(Object bean, String beanName) {
f (! (bean instanceof BeanPostProcessor) &&!this.isInfrastructureBean (beanName) G& this. beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount && Logger.isInfoEnabled()) {
… log message
Can anyone assist
Thanks

Related

Spring not recognising some #Configuration and #Component classes

I have - or rather had - a working Spring application, running within IntelliJ. It contains several classes annotated with #Configuration, and several #Component beans. At some point, the following happened:
Intelli started showing errors in the code editor stating "Could not autowire. No bean of 'xxx' type found". But there are such beans which are annotated with #Component.
Breakpoints in the constructor of specific #Component beans are not reached. But that is not true for all #Component beans.
When running in debug mode, breakpoints in certain #Configuration files are not reached, even though the debugger was stopping there before. The application will fail if it is autowired with one of these #Component beans.
The application starts without errors, but obviously without several beans configured in #Configuration classes being called.
The class which contains the main method which runs the Spring Boot application is annotated with #SpringBootApplication. #Component classes which live in the same package as this class are recognised and can be autowired, even into classes in other packages.
I am not aware of anything in the code or project which would have changed.
Under File -> Project Settings -> Modules, under Spring Application Context have now selected all #Configuration files. However this makes no difference.
Have also tried Build -> Rebuild Project.
The packages in which the classes reside have not changed. Has anyone seen anything like this before?
Thanks
If few classes are not getting recognised #Component. Then it could be the case that those classes don't come under the same package. You must have observed that the classes under the same package as of Main class of #SpringBootApplication, got recognised with #Component because #SpringBootApplication defines an automatic #ComponentScan on the package.
So other classes which were defined in some other package are not recognised because there is no #ComponentScan for those classes' package.
You can do the following to get those classes recognised(add the other packages which are not directly under the hierarchy of #SpringBootApplication):
#ComponentScan({"com.example.springboot.anything","com.example.springboot.somethingelse"})
#SpringBootApplication
public class AnySpringBootApplication {
I am sure it will not be a common case, but for me the problem was that my class had a relatively generic name. Although it was located in the package mentioned in the ComponentScan, on the same level with other classes all found and used, I kept having problems that the ApplicationContext failed to load. After I renamed the class it worked, I found that two other classes in org.springframework had the same name.

spring-aop "None or multiple beans found in Spring context for type class"

I am not able to apply an aspect to my spring rest endpoint components for logging purposes.
All of endpoint classes are implemented like
#Component
#Path("mypath")
public class MyEndpointImpl extends MyEndpoint
{...}
Without aspect everything works fine without any errors. When I try to apply aspect I just get list of errors for each endpoint class like "None or multiple beans found in Spring context for type class **.*EndpointImpl" and no aspect is intercepting endpoints' methods. However everything works fine as if there were no error message and no aspect.
Interesting is when I create e.g. simple filter
#Component
#WebFilter(filterName = "MySimpleFilter", urlPatterns = "/*")
public class SimpleFilter implements javax.servlet.Filter
{...}
in package of pointcut, doFilter method of SimpleFilter is intercepted by the aspect as would expect for all endpoint methods.
What could be a problem here, any ideas?
In my environment the Problem disappeared when adding the following to the application.yml file
spring.aop.proxy-target-class: true

How to get Spring Boot to create a bean validator before creating all the other beans

I'm trying to add a LocalValidatorFactoryBean to an existing Spring Boot web application.
No matter what I have tried (listed in a moment) it only creates the validator after most other beans (verified with both logging and breakpoints), so they never get validated.
Tangentially, I have hibernate-validator on the classpath and am attempting to use javax.validation.constraints on my #Component properties.
Application class has #Configuration, #EnableAutoConfiguration and #ComponentScan({"my.package.**"}).
Adding an application.xml with the bean <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
Adding the above bean to validator.xml and adding #ImportResource("validator.xml")
Adding a new #Bean to the Application class. public Validator validator() { return new LocalValidatorFactoryBean(); }
Adding #Order(Ordered.HIGHEST_PRECEDENCE) to the above #Bean
Adding a BeanValidator #Component to the scanned packages.
And adding #Order to it.
In all cases, the validator is loaded only after FilterRegistrationBean has finished logging its business, but the beans I want to validate have already been created and used in setting up data connections and security for example.
Its been a few years since I've used Spring, but I don't remember these problems when defining everything in an application.xml. Is this just something that spring-boot doesn't support and I should move back to traditional Spring application config?
How can I get it to validate all my beans?
I forgot to make a BeanValidationPostProcessor.

How to invoke Spring BeanPostProcessor within HK2

I have a Jersey 2 application using the jersey-spring bridge. However, it seems that BeanPostProcessors declared in my application context are never invoked on resources created by Jersey (which actually delegates all this to HK2). I think that the Jersey-Spring bridge only care about resources annotated with #Component and fields annotated with #Autowired.
I was wondering how I could actually automatically invoke BeanPostProcessor's on newly created Jersey resources.
I found that there was an InstanceLifecycleListener but I was unable to find any documentation on this can be used.

#Qualifier and #Resource doesn't work when running test case under Spring test framework

I have a test case which has a dependency of 'ticketDao', like below:
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
public class LfnSaleCancellationIntegrationTest extends BaseIntegrationTest {
//#Resource(name = "baseTicketDao")
private BaseTicketDao ticketDao;
....
public void setTicketDao(#Qualifier("baseTicketDao") BaseTicketDao ticketDao) {
this.ticketDao = ticketDao;
}
}
and BaseIntegrationTest extends from spring test framework's AbstractJpaTests, Spring is v3.0.5
When run this test case, I got a similar exception:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [com.mpos.lottery.te.gamespec.sale.dao.BaseTicketDao]
is defined: expected single matching bean but found 2:
[baseTicketDao, extraballTicketDao]
My project has evolved a long time, in fact when I encountered this exception at the first time, #Qualifier solved it. Till today this project has changed much, but I really have no idea why #Qaulifier and #Resource don't work any more.
And if i remove the dependency of 'ticketDao', the test case will pass. I am wondering whether there are some change of spring configuration cause this exception? or ... i have googled much, but seem no other people ever faced such a problem, pls give your comments, thanks very much!
You are using AbstractJPATests which is part of old spring test framework and (indirect) subclass of AbstractDependencyInjectionSpringContextTests. By default the injection is not annotation based but it discovers setters and fields and attempts injection by type. It would be recommended to switch to newer annotation based tests, refer to spring documentation for details.
As a workaround try to change autowire mode. Call it in test constructor as this.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME), rename your field to baseTicketDao and remove setter.
I knew the reason. In my new project, there are a statement of context:component-scan in spring configuration file, which will register 4 BeanPostProcessors by default:
AutowiredAnnotationBeanPostProcessor(#Autowired)
RequiredAnnotationBeanPostProcessor(#Require)
CommonAnnotationBeanPostProcessor(JSR-250 annotations, #Resource, #PostConstruct etc, #WebServiceRef )
PersistenceAnnotationBeanPostProcessor(#PersistenceUnit and #PersistenceContext)
While in my old project, only the default BeanPostProcessor(internalAutoProxyCreator) has been registered. My understanding is AutowiredAnnotationBeanPostProcessor will always wire by type. Anyway if remove context:component-scan, my test case can pass now.
In fact i have migrate all my test cases to spring test context framework now, and context:component-scan must be stated, otherwise #Autowired, #Resource etc annotation will be ignored, and you will get a great many of NullPointerException of those automaticaly injected dependencies.
NOTE: <context:annotation-config/> will register those 4 BeanPostProcessors too.

Resources