How to autowire #ConfigurationProperties into #Configuration? - spring

I have a properties class defined like this:
#Validated
#ConfigurationProperties(prefix = "plugin.httpclient")
public class HttpClientProperties {
...
}
And a configuration class like this:
#Configuration
#EnableScheduling
public class HttpClientConfiguration {
private final HttpClientProperties httpClientProperties;
#Autowired
public HttpClientConfiguration(HttpClientProperties httpClientProperties) {
this.httpClientProperties = httpClientProperties;
}
...
}
When starting my spring boot application, I'm getting
Parameter 0 of constructor in x.y.z.config.HttpClientConfiguration required a bean of type 'x.y.z.config.HttpClientProperties' that could not be found.
Is this not a valid use case, or do I have to declare the dependencies some how?

This is a valid use case, however, your HttpClientProperties are not picked up because they're not scanned by the component scanner. You could annotate your HttpClientProperties with #Component:
#Validated
#Component
#ConfigurationProperties(prefix = "plugin.httpclient")
public class HttpClientProperties {
// ...
}
Another way of doing so (as mentioned by Stephane Nicoll) is by using the #EnableConfigurationProperties() annotation on a Spring configuration class, for example:
#EnableConfigurationProperties(HttpClientProperties.class) // This is the recommended way
#EnableScheduling
public class HttpClientConfiguration {
// ...
}
This is also described in the Spring boot docs.

In Spring Boot 2.2.1+, add the #ConfigurationPropertiesScan annotation to the application. (Note that this was enabled by default in version 2.2.0.) This will allow all classes annotated with #ConfigurationProperties to be picked up without using #EnableConfigurationProperties or #Component.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
#SpringBootApplication
#ConfigurationPropertiesScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Also, to generate metadata for the classes annotated with #ConfigurationProperties, which is used by IDEs to provide autocompletion and documentation in application.properties, remember to add the following dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

Related

Should #ComponentScan stay in the class containing the main method?

I know that #ComponentScan with #Configuration tell Spring where to look for beans.
#ComponentScan
#Configuration
public class MyApp{
...
}
What I do not understand is on which class I have to put these two annotations. Should they stay on the class containing the main method?
Like this
#ComponentScan
#Configuration
public class MyApp{
public static void main(String[] args) {
...
}
}
Or they can stay on whatever class of the application?
The question comes from the fact that Spring has to know the location of #ComponentScan... or is there an automatic way of detection of the #ComponentScan annotation which Spring is performing under the hood?
Hope to have explained myself!
You can put it wherever you want (I usually put mine in com.domain.project-name.config) and just specify the directories it should scan, for example if you want it to scan everything in project use
#ComponentScan("com.domain.project-name")
#Configuration
public class Config {
...
By default, ComponentScan scans all the annotated classes at the current directory level and below.
#Configuration annotation tells the Spring container that the class contains Spring bean configuration.
#ComponentScan annotation tells the Spring container that the annotated class to scan/searches for other annotations and components. You can also define package name to scan with the annotation like #ComponentScan("your.package.name") or you can give package/class names that need not be scanned.
Hence, you can put these annotations on any class that defines your bean configuration and could be required by spring container to parse and create objects for your entities/POJOs, services and DAOs.
To conclude, I would like to add #ComponentScan and other annotations are there for automatic detection. Else, you would need to define XMLs (that's what happens under the hood with annotations) for spring to read and perform these actions.
Using simple example. You can place #ComponentScan with #Configuration in any class which main method can scan.
Main class scans MyScan class which then scan for bean class.
package com.boot.spring;
#SpringBootApplication
#ComponentScan(basePackages = "com.boot.scan")
public class BootApplication {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(BootApplication.class, args);
System.out.println(ctx.getBean("demoBean"));
}
}
Bean class is in different package
package com.boot.bean;
#Service
public class DemoBean {
}
Now, bean class is discovered through DemoScan class
package com.boot.scan;
#ComponentScan(basePackages = "com.boot.bean")
#Configuration
public class DemoScan {
}

Spring Java Config: configure already existing bean

I want to configure in my #Configuration class bean which is already created by other library's autoconfiguration. I just need to change some fields in that class after it's being initialized.
But I can't find a proper way how to provide code block in #Configuration class and not using #Bean annotation. Is there an ideomatic way to do so in spring?
One way to do this:
#Configuration
class TestConfig {
#Autowired
private SomeBean someBean;
#PostConstruct
private void initSomeBean() {
// someBean.setProperty("qwe");
}
}
#PostConstruct annotation defines init-method, which is getting called after SomeBean is autowired. In this method you can adjust your bean
Do you want to import one Config in AnotherConfig on? It can be done via annotation placed on AnotherConfig:
import org.springframework.context.annotation.Import;
...
#Import(value = {Config.class})
public class AnotherConfig ... {}

Spring Boot AOP in multi module project does not execute Before Advice

I'm doing my fist steps with Springs AOP and wanted to start with a simple logging advice. My project is a multi module maven project with the following structure:
parentProject
|__aop
|__data
|__web
The web module has a user service class in the package de.my.awsome.project.web.service with a saveNewUser Method:
#Service
public class UserService {
...
public MdUser saveNewUser(UserModel user) {
MdUser newUser = this.save(user);
createGroupMembership(user, newUser);
return newUser;
}
}
The method works as expected so don't bother with details about that.
What I've done now is to create the following class in the aop module:
#Component
#Aspect
public class LoggingAspect {
Logger logger = Logger.getLogger(getClass());
#Before("execution(public * de.my.awsome.project.web.service.UserService.saveNewUser(..))")
public void newUserLog(JoinPoint joinpoint) {
logger.info(joinpoint.getSignature() + " with user " + joinpoint.getArgs()[0]);
}
}
I added a dependency for the web module in the pom of the aop module:
<dependency>
<groupId>de.my.awsome.project</groupId>
<artifactId>web</artifactId>
<version>${project.version}</version>
</dependency>
I even wrote a ConfigurationClasse even though I thought this would not be necessary with SpringBoot:
#Configuration
#ComponentScan(basePackages="de.fraport.bvd.mobisl.aop")
public class AspectsConfig {
}
The expected result is a log-message like "saveNewUser with user xyz". But the logging method is never called. What have I missed to do?
#Configuration - Indicates that this file contains Spring Bean Configuration for an Aspect.
Replace #Component with #Configuration for LoggingAspect.
Well, the answer that #sankar posted didn't work either but I found the solution by myself.
I had to add a dependency to my aop module in the web modules pom, not vice versa. Then I added an Import of my AspectsConfig to the web modules SpringBootApplication class and it worked.
#SpringBootApplication
#Import(value= {JPAConfig.class, AspectsConfig.class})
#EnableAspectJAutoProxy
public class WebApplication {
#Autowired
private JPAConfig config;
#Autowired
private AspectsConfig aspectConfig;
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
The following steps work for me - see below if anyone is looking for a solution
add the aop dependency in to the main parent pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
add your Aspect implementation in he aop-sub-module
#Aspect
#Component
public class SampleAspect {
#After("execution(* de.my.awsome.project.testMethod())")
public void logAuditActivity(JoinPoint jp) {
System.out.println("TESTING ****************");
System.out.println("The method is called");
}
In your other submodule (web-submodule) add the dependancy of the aspect-submodule
<dependency>
<groupId>de.my.awsome.project</groupId>
<artifactId>aop</artifactId>
</dependency>
In your web Project include the aop package for component scan
eg. if SampleAspect is under a package de.my.awsome.project you will need to add in as follow
#ComponentScan(basePackages = {"de.my.awsome.project", "de.my.awsome.aop" }
clean build and run the app

Disable all Database related auto configuration in Spring Boot

I am using Spring Boot to develop two applications, one serves as the server and other one is a client app. However, both of them are the same app that function differently based on the active profile. I am using auto configuration feature of Spring Boot to configure my applications.
I want to disable all the database related auto configuration on client app, since it won't be requiring database connection. Application should not try to establish connection with the database, nor try to use any of the Spring Data or Hibernate features. The enabling or disabling of the database auto configuration should be conditional and based on the active profile of the app.
Can I achieve this by creating two different application.properties files for respective profiles?
I tried adding this to my properties file,
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
But, the application still tries to connect to the database on start. Are those exclusions sufficient for achieving my requirement?
The way I would do similar thing is:
#Configuration
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
#Profile ("client_app_profile_name")
public class ClientAppConfiguration {
//it can be left blank
}
Write similar one for the server app (without excludes).
Last step is to disable Auto Configuration from main spring boot class:
#SpringBootApplication
public class SomeApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class);
}
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SomeApplication.class);
}
}
Change: #SpringBootApplication into:
#Configuration
#ComponentScan
This should do the job. Now, the dependencies that I excluded in the example might be incomplete. They were enough for me, but im not sure if its all to completely disable database related libraries. Check the list below to be sure:
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#auto-configuration-classes
For disabling all the database related autoconfiguration and exit from:
Cannot determine embedded database driver class for database type NONE
1. Using annotation:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(PayPalApplication.class, args);
}
}
2. Using Application.properties:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Seems like you just forgot the comma to separate the classes. So based on your configuration the following will work:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
Alternatively you could also define it as follow:
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[2]=org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
spring.autoconfigure.exclude[3]=org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
There's a way to exclude specific auto-configuration classes using #SpringBootApplication annotation.
#Import(MyPersistenceConfiguration.class)
#SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
#SpringBootApplication#exclude attribute is an alias for #EnableAutoConfiguration#exclude attribute and I find it rather handy and useful.
I added #Import(MyPersistenceConfiguration.class) to the example to demonstrate how you can apply your custom database configuration.
Way out for me was to add
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
annotation to class running Spring boot (marked with `#SpringBootApplication).
Finally, it looks like:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
If using application.yml:
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
- org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
Another way to control it via Profiles is this:
// note: no #SpringApplication annotation here
#Import(DatabaseConfig.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#Configuration
#Import({DatabaseConfig.WithDB.class, DatabaseConfig.WithoutDB.class})
public class DatabaseConfig {
#Profile("!db")
#EnableAutoConfiguration(
exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
static class WithoutDB {
}
#Profile("db")
#EnableAutoConfiguration
static class WithDB {
}
}
I had the same problem here, solved like this:
Just add another application-{yourprofile}.yml where "yourprofile" could be "client".
In my case I just wanted to remove Redis in a Dev profile, so I added a application-dev.yml next to the main application.yml and it did the job.
In this file I put:
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
this should work with properties files as well.
I like the fact that there is no need to change the application code to do that.
I add in myApp.java, after #SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
And changed
#SpringBootApplication => #Configuration
So, I have this in my main class (myApp.java)
package br.com.company.project.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class SomeApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
}
And work for me! =)
In my case the spring-boot-starter-jpa dependency was being loaded from other dependency. I did this to disable the DataSource:
Check the dependency tree with mvn dependency:tree
[INFO] com.backend.app:crud-manager:jar:0.1-SNAPSHOT
[INFO] +- ...
[INFO] \- com.backend.app:crud-libraries:jar:0.1-SNAPSHOT:compile
[INFO] +- org.springframework.boot:spring-boot-starter.data-jpa:jar:2.1.6.RELEASE:compile
[INFO] +- ....
There was a sub-dependency. Add an exclusion
<dependency>
<groupId>com.backend.app</groupId>
<artifactId>crud-libraries</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusion>
</exclusions>
</dependency>
Exclude DataSourceAutoConfiguration.class in the Application file
import org.springframework.boot.autoconfigure.jdbc. DataSourceAutoConfiguration;
// add exclude
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ...
Ensure there is no spring-boot-starter-jpa in pom.xml
** Apart, in case you also need to make it work with spring-boot-starter-batch
In the BatchConfig file:
// add extends DefaultBatchConfig
public class BatchConfig extends DefaultBatchConfig {
//add override
#Override
public void setDataSource(DataSource dataSource) {}
I was getting this error even if I did all the solutions mentioned above.
by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfig ...
At some point when i look up the POM there was this dependency in it
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
And the Pojo class had the following imports
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
Which clearly shows the application was expecting a datasource.
What I did was I removed the JPA dependency from pom and replaced the imports for the pojo with the following once
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
Finally I got SUCCESSFUL build. Check it out you might have run into the same problem
Also if you use Spring Actuator org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration might be initializing DataSource as well.
By default in Spring, all the defined beans, and their dependencies, are created when the application context is created.
In contrast, when we configure a bean with lazy initialization, the bean will only be created, and its dependencies injected, once they're needed.
spring:
main:
lazy-initialization: true
jpa:
properties:
hibernate: # lazy-initialization works with this dialect property to avoid run issues if DB is Down
dialect: org.hibernate.dialect.Oracle10gDialect

#Autowired dependencies are null in compile time weaving of #Aspect class [duplicate]

I have the following spring configuration:
<context:component-scan base-package="uk.co.mysite.googlecontactsync.aop"/>
<bean name="simpleEmailSender" class="uk.co.mysite.util.email.simple.SimpleEmailSenderImplementation"/>
<aop:aspectj-autoproxy/>
Then I have an aspect:
#Aspect
public class SyncLoggingAspect {
#Autowired
private SimpleEmailSender simpleEmailSender
#AfterReturning(value="execution(* uk.co.mysite.datasync.polling.Poller+.doPoll())", returning="pusher")
public void afterPoll(Pusher pusher) {
simpleEmailSender.send(new PusherEmail(pusher));
}
}
This aspect works (I can hit a breakpoint on afterPoll) but simpleEmailSender is null. Unfortunately I cannot find clear documentation on why this is. (For the record, my simpleEmailSender bean exists and is correctly wired into other classes) The following things confuse me:
Is context:component-scan supposed to be picking up #Aspect? If it is then surely it would be a spring managed bean, thus autowired should work?
If context:component-scan isn't for creating aspects, how is my aspect being created? I thought aop:aspectj-autoproxy just creates a beanPostProcessor to proxy my #Aspect class? How would it do this if it isn't a spring managed bean?
Obviously you can tell I don't have an understanding of how things should be working from the ground up.
The aspect is a singleton object and is created outside the Spring container. A solution with XML configuration is to use Spring's factory method to retrieve the aspect.
<bean id="syncLoggingAspect" class="uk.co.demo.SyncLoggingAspect"
factory-method="aspectOf" />
With this configuration the aspect will be treated as any other Spring bean and the autowiring will work as normal.
You have to use the factory-method also on Enum objects and other objects without a constructor or objects that are created outside the Spring container.
For Spring Boot to use #Autowired with AspectJ I have found the following method.
In configuration class add your aspect:
#Configuration
#ComponentScan("com.kirillch.eqrul")
public class AspectConfig {
#Bean
public EmailAspect theAspect() {
EmailAspect aspect = Aspects.aspectOf(EmailAspect.class);
return aspect;
}
}
Then you can successfully autowire your services in your aspect class:
#Aspect
public class EmailAspect {
#Autowired
EmailService emailService;
Another option is to add #Configurable to your aspect class instead of messing around with XML.
Configuring #Autowired with java config only (so no XML based configuration) requires a bit of extra work than just adding #Configuration to the class, as it also needs the aspectOf method.
What worked for me was creating a new class:
#Component
public class SpringApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
And then use that in you aspect in conjunction with using #DependsOn #Configured and #Autowired:
#DependsOn("springApplicationContextHolder")
#Configuration
#Aspect
public class SomeAspect {
#Autowired
private SomeBean someBean;
public static SomeAspect aspectOf() {
return SpringApplicationContextHolder.getApplicationContext().getBean(SomeAspect.class);
}
The #DependsOn is needed because spring can't determine the dependency because the bean is used staticly.
I dont have 50 rep to comment on a question so here is another answer relating to #
Jitendra Vispute answer.
The official Spring doc mentions:
You may register aspect classes as regular beans in your Spring XML configuration, or autodetect them through classpath scanning - just like any other Spring-managed bean. However, note that the #Aspect annotation is not sufficient for autodetection in the classpath: For that purpose, you need to add a separate #Component annotation (or alternatively a custom stereotype annotation that qualifies, as per the rules of Spring’s component scanner).Source: Spring '4.1.7.Release' documentation.
This would mean that adding a #Component annotation and adding the #ComponentScan on your Configuration would make #Jitendra Vispute's example work. For the spring boot aop sample it worked, though I did not mess around with context refreshing.Spring boot aop sample:
Application:
package sample.aop;
#SpringBootApplication
public class SampleAopApplication implements CommandLineRunner {
// Simple example shows how an application can spy on itself with AOP
#Autowired
private HelloWorldService helloWorldService;
#Override
public void run(String... args) {
System.out.println(this.helloWorldService.getHelloMessage());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleAopApplication.class, args);
}
}
The application should also run as plain Spring Framework application with the following annotations instead of #SpringBootApplication:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan
and an AnnotationConfigApplicationContext instead of SpringApplication.
Service:
package sample.aop.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class HelloWorldService {
#Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}
Monitor Aspect:
package sample.aop.monitor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class ServiceMonitor {
#AfterReturning("execution(* sample..*Service.*(..))")
public void logServiceAccess(JoinPoint joinPoint) {
System.out.println("Completed: " + joinPoint);
}
}
This blog post explains it really well. Due to the fact that aspect singleton is created outside spring container you'd need to use factory-method=”aspectOf” that is only available after it is woven in by AspectJ ( not Spring AOP ) :
Notice factory-method=”aspectOf” that tells Spring to use a real
AspectJ ( not Spring AOP ) aspect to create this bean. So that after
the aspect is woven in it has an
“aspectOf” method.
So that :
No matching factory method found: factory method 'aspectOf()' - That
would mean that the aspect was not woven by AspectJ weaver.
From my experience with spring 3.1, if I don't use #Autowired but traditional setter for dependency injection, it gets injected and works as expected without aspectJ weaver. Although I'm encountering problems with the aspect being singleton... It results in 'perthis' instantiation model.
.
Add #Component to aspect class and your dependencies should get injected automatically.
and add context:component-scan for package where your aspect is in spring context file.
#Component
#Aspect
public class SomeAspect {
/* following dependency should get injected */
#Autowired
SomeTask someTask;
/* rest of code */
}
Use compile time weaving, see for plugin example at: https://github.com/avner-levy/minimal_spring_hibernate_maven_setup/blob/master/pom.xml
The following combination of annotation and Spring config works for me thanks to notes above by Tobias/Willie/Eric:
Class:
package com.abc
#Configurable
#Aspect
public class MyAspect {
#Autowired
protected SomeType someAutoWiredField;
}
XML:
<context:spring-configured />
<context:component-scan base-package="com.abc" />
#Configurable(autowire = Autowire.BY_TYPE)
Add this annotation to your Aspectj class. Then it will be handled by Spring IOC.
For Spring Boot using #Autowired in #Aspect,
my way is using spring.factories configuration file
create a file named spring.factories in src/main/resources
the file content is as following
org.springframework.boot.autoconfigure.EnableAutoConfiguration=pack.age.to.YourAspect,pack.age.to.YourDAO

Resources