Reputation: 533
I've managed to avoid developing any xml files so far for my Spring Boot Maven project (apart from the pom) with them all being generated on compile and I was hoping to keep this way by defining my profiles within the run commands as specified here.
By simply using @ComponentScan my main class to enable the scanning of components and tagging my DAO as @Repository I have successfully managed to autowire my UserDAOmySQLImpl class (which inherits UserDAO).
@Autowired
private UserDAO userDAO;
Then looking forward to add a second DAO for when in Live where we use a db8 implementation I need the application to figure out which UserDAO implementation needs to be used. Profiles seemed to be the answer.
After some reading, it seemed that mostly I need to add in some sort of configuration classes and external xml to manage these profiles and components, though this seems messy and I am hoping unnecessary.
I have tagged by two implementations as so:
@Repository
@Profile("dev")
public class UserDAOmySQLImpl implements UserDAO {...
-
@Repository
@Profile("dev")
public class UserDAOdb8Impl implements UserDAO {...
And then set the active profile through the Maven goals as specified here in hope that this would be a nice clean solution so I could specify the active profile within the goal for our dev and live build scripts respectively.
My current goal for testing is:
spring-boot:run -Drun.profiles=dev
However, when building I receive an error that both beans are being picked up.
*No qualifying bean of type [com.***.studyplanner.integration.UserDAO] is defined: expected single matching bean but found 2: userDAOdb8Impl,userDAOmySQLImpl*
Questions
Is the profile set in the Maven Goal the one being checked against when using the @Profile tag?
Why is Spring picking up both implementations, when if the profile isn't being set properly surely neither implementation should be selected?
Any suggestions on a nice clean way to achieve what I'm looking for?
Bonus
I would really like to set the profile within the app, as it would be easy to simply check whether an environment file exists to decide which profile to use, though I'm struggling to replicate this (found within Spring Profiles Examples
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//Enable a "live" profile
context.getEnvironment().setActiveProfiles("live");
context.register(AppConfig.class);
context.refresh();
((ConfigurableApplicationContext) context).close();
}
in to the unusual main class in the application I am working on which I am hesitant to play around with.
public class StudyPlannerApplication {
...
public static void main(String[] args) {
SpringApplication.run(StudyPlannerApplication.class, args);
}
...
}
Any help would much appreciated.
Cheers, Scott.
Upvotes: 0
Views: 2645
Reputation: 533
Silly me, proof reading the question I noticed that a bad copy & paste job meant that both DAO implementations had the @profile set to "Dev". After changing the db8 DAO to @Profile("live") the above works fine.
So to choose your repository based on profile is actually quite easy when using maven and spring boot.
1) Ensure your main class has the @ComponentScan annotation
@ComponentScan
public class StudyPlannerApplication {
2) Tag your components with the @Profile tags according to which profile you would like them sectected for
@Repository
@Profile("dev")
public class UserDAOdb8Impl implements UserDAO {...
-
@Repository
@Profile("live")
public class UserDAOdb8Impl implements UserDAO {...
3) Send your profile in with your maven goal
spring-boot:run -Drun.profiles=dev
Hopefully this will help others, as I haven't seen a full example of using the autowiring profiles as I have done elsewhere on the web
Upvotes: 1