Scott Allen
Scott Allen

Reputation: 533

Can I use @Profile Tags on Components without creating an @Configuration class in Spring Boot or a Web.xml

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

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

Answers (1)

Scott Allen
Scott Allen

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

Related Questions