Requested bean is currently in creation: Is there an unresolvable circular reference when use AspectJ and security - spring

Hi i am developing a web application with using spring security and doing logging with AspectJ.
When i add new bean which is created with AspectJ getting this error.
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'loggingAspect': Requested bean is currently in creation: Is there an unresolvable circular reference?
My Spring configuration file ;
#Configuration
#EnableWebMvc
#EnableAspectJAutoProxy
#ComponentScan( basePackages = { "com.org" } )
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public LoggingAspect loggingAspect() {
return new LoggingAspect();
}
My Spring security configuration file with annotation;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { }
Logging aspect
#Aspect
#Component
public class LoggingAspect {
/**
* Default Constructor.
*/
public LoggingAspect() {
}
I can't create this bean and couldn't find any solution.
May anyone help for this please.
Thanks.

Related

SpringBoot 2.1 spring.main.allow-bean-definition-overriding=true not working

We are upgrading to SpringBoot 2.1.x and Spring Security 5.1.x. We have our own SecurityConfig that overrides springSecurityFilterChain bean that is found in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration. I have added that property to the applications.property file and set it to true but it is still not allowing overrides.
Our class:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public FilterChainProxy springSecurityFilterChain() throws Exception {
blahblahblah
}
}
And the Spring class:
package org.springframework.security.config.annotation.web.configuration;
#Configuration
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
#Bean(
name = {"springSecurityFilterChain"}
)
public Filter springSecurityFilterChain() throws Exception {
blahblah
}
}
The error:
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'springSecurityFilterChain' defined in class path resource
Its not clear to me why setting the override property to true is not being picked up. I have also tried to annotate our bean as primary, the #autoconfigureBefore(WebSecurityConfiguration.class) and removing non-wanted bean from registry (but haven't figured out how to do that successfully). Is there something special about the bean I am trying to override that prevents it? Do I need to have the applications.property file loaded earlier somehow?
same issue here. what is the solution for this. I have
#Bean
#Primary
public ScheduledLockConfiguration taskScheduler(LockProvider lockProvider) {
}
But it doesn't seem to be invoked as another bean in third party library exists with same name.

Will declaring #configuration on a class make it a spring bean?

I am having a spring boot project and I have a class declared with #configuration annotation.
will declaring a class with #configuration make it a spring bean ?. so here is my code below
#Configuration
public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new PaginationArgumentResolver());
argumentResolvers.add(new FlightFilterArgumentResolver());
argumentResolvers.add(new CampaignFilterArgumentResolver());
argumentResolvers.add(new ContactListFilterArgumentResolver());
argumentResolvers.add(new UserFilterArgumentResolver());
argumentResolvers.add(new PrimecastAccountFilterArgumentResolver());
argumentResolvers.add(new MessageHistoryFilterArgumentResolver());
}
}
Will the above code results in the creation of a spring bean DateTimeFormatConfiguration in the application context when it is started?
Yes. #Configuration annotated class will register as a spring bean. Check the following snippet from documentation. The primary purpose of #configuration to act as a bean source.
When #Configuration classes are provided as input, the #Configuration
class itself is registered as a bean definition, and all declared
#Bean methods within the class are also registered as bean
definitions.
[1] https://docs.spring.io/spring/docs/4.3.25.RELEASE/spring-framework-reference/htmlsingle/#beans-java-basic-concepts

Adding #Conditional to an existing spring annotation in spring boot

I have an application which uses an existing spring annotation (#EnableResourceServer). I want this particular annotation to be enabled only when a particular property value is not false.
To do this, I created a meta-annotation and applied #ConditionalOnProperty on that :
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
#ConditionalOnProperty(prefix = "custom.resource", name = "enabled", matchIfMissing = true)
#EnableResourceServer
public #interface EnableCustomResourceSecurity {
}
In my application I'm now using #EnableCustomResourceSecurity like :
#EnableCustomResourceSecurity
#SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
and it all works fine if the property is missing or true but when I change the property to custom.resource.enabled=false I get the following exception :
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
I tried putting this annotation in a couple of other places and noticed that when the conditional expression fails for this annotation, any annotation after this also stops getting processed.
What would be the correct way to achieve what I'm trying to do?
Your annotation #EnableCustomResourceSecurity has the meta annotation #ConditionalOnProperty. While it may seem as if it enables/disables the #EnableResourceServer annotation, it actually enables/disables your MyApplication bean as a whole. It is as if you would write:
#SpringBootApplication
#ConditionalOnProperty(...)
#EnableResourceServer
public class MyApplication {
To avoid this, simply create an empty SomeConfiguration class and annotate it with your custom annotation:
#Configuration
#EnableCustomResourceSecurity
public class SomeConfiguration {}
Instead of adding it to your MyApplication class.
I would recommend, you don't even need a custom annotation but just an empty configuration as mentioned by Michiel. This configuration, in turn, will also import the #EnableResourceServer annotation.
#Configuration
#EnableResourceServer
#ConditionalOnProperty(prefix = "custom.resource", name = "enabled", matchIfMissing = true)
public class ResourceServerConfig {
public ResourceServerConfig() {
System.out.println("initializing ResourceServerConfig ...");
}
}
If you want to control based on annotation, you can import the same configuration in the custom annotation as below:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
#Import(ResourceServerConfig.class)
public #interface EnableCustomResourceSecurity {
}

Overriding and extending bean if application run on given profile

So let's say I've main bean annotated with #Service which is injected in another services with #Autowired.
#Service
#Order(100)
class MainService() {
fun helloWorld() = "Hello"
}
And I would like to extend this service when running with another profile fg. ("custom"). So I have service as below:
#Service("mainService")
#Order(1)
class CustomService: MainService() {
override fun helloWorld() = "Hello custom"
}
But I'm getting this exception:
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'mainService' for bean class [MainService] conflicts with existing, non-compatible bean definition of same name and class [CustomService]
Have you any idea how could I extend and override bean under the same name? Its because I need to autowire it somewhere else
You can use configuration beans to do this:
#Configuration
#Profile("dev")
public class MainServiceDev {
#Bean
public MainService mainService() {
return new MainService();
}
}
#Configuration
#Profile("custom")
public class MainServiceCustom {
#Bean
public CustomService customService() {
return new CustomService();
}
}

Spring: Properly setup #ComponentScan

I have following set up for my Spring Application Context.
#Configuration
public class RmiContext {
#Bean
public RmiProxyFactoryBean service() {
RmiProxyFactoryBean rmiProxy = new RmiProxyFactoryBean();
rmiProxy.setServiceUrl("rmi://127.0.1.1:1099/Service");
rmiProxy.setServiceInterface(Service.class);
return rmiProxy;
}
}
#Configuration
public class LocalContext {
#Bean
public Controller Controller() {
return new ControllerImpl();
}
}
#Configuration
#Import({RmiContext.class, LocalContext.class})
public class MainContext {
}
The above setup works fine, but I want to enable #ComponentScan annotating Controllers with #Component as there are many Controllers in my application which is tedious when declared one by one using #Bean.
#Configuration
#ComponentScan(basePackageClasses = {Controller.class})
public class LocalContext {
/* ... */
}
The problem is that when I do #ComponentScan(basePackageClasses = {Controller.class}), the previously fine working RmiProxyFactoryBean are not recognized or can't be created.
So, How do I configure my MainContext so that both beans via RMI and local beans are created?
#Configuration is also a candidate for component scan, so you can scan all the beans in RmiContext and all controllers in your controller package by:
#Configuration
#ComponentScan(basePackages = {"org.example.controllers", "package.of.RmiContext"})
public class MainContext {
}
--edit--
#Configuration is a candidate for component scan, here is the test case that works in my pc:
package scan.controllers;
#Controller
public class ExampleController {
}
package scan;
public interface RMIService {
}
package scan;
#Configuration
public class RmiContext {
#Bean
public RmiProxyFactoryBean service() {
RmiProxyFactoryBean rmiProxy = new RmiProxyFactoryBean();
rmiProxy.setServiceUrl("rmi://127.0.1.1:1099/Service");
rmiProxy.setServiceInterface(RMIService.class);
rmiProxy.setLookupStubOnStartup(false);
return rmiProxy;
}
}
package scan;
#Configuration
//MainContext will auto scan RmiContext in package scan and all controllers in package scan.controllers
#ComponentScan(basePackages = {"scan", "scan.controllers"})
public class MainContext {
}
package scan;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={MainContext.class})
public class TestContext {
#Autowired private RMIService rmi;
#Autowired private ExampleController controller;
#Test
public void test() {
//both controller and rmi service are autowired as expected
assertNotNull(controller);
assertNotNull(rmi);
}
}
May be you could try using the base packages of your classes (RMI, Controller):
#ComponentScan(basePackages = {"your controller package", "your rmi package"})
If the RMI classes package is different than controller then they will fail to instantiate by spring.
If I understand you correctly, you use "#ComponentScan(basePackageClasses" but it is not detecting and registering your spring beans?
I had the same issue a few minutes ago. I did not give up and tried all funny guesses. One guess did it.
I had to add an XML component-scan entry in XML. I just put a dummy package there, like below:
component-scan base-package="dummy.filler.to.enable.component.scan"
It seems that the component-scan in XML enables the #ComponentScan.
[Late Edit: I noticed, my spring xml schema is spring 2.5. Anyway, I dont know if this matters. Best Regards.]

Resources