Stvorite prilagođenu automatsku konfiguraciju pomoću Spring Boot-a

1. Pregled

Jednostavno rečeno, automatska konfiguracija Spring Boot predstavlja način za automatsko konfiguriranje Spring aplikacije na temelju ovisnosti koje su prisutne na putu predavanja.

To može ubrzati i olakšati razvoj uklanjanjem potrebe za definiranjem određenih grahova koji su uključeni u klase automatske konfiguracije.

U sljedećem ćemo odjeljku pogledati stvarajući našu prilagođenu automatsku konfiguraciju Spring Boot.

2. Ovisnosti Mavena

Počnimo s ovisnostima koje su nam potrebne:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.2.OSLOBODI mysql mysql-konektor-java 8.0.19 

Najnovije verzije spring-boot-starter-data-jpa i mysql-connector-java mogu se preuzeti s Maven Central.

3. Izrada prilagođene automatske konfiguracije

Da bismo stvorili prilagođenu automatsku konfiguraciju, moramo stvoriti klasu označenu sa @Konfiguracija i registrirajte ga.

Stvorimo prilagođenu konfiguraciju za MySQL izvor podataka:

@Configuration javna klasa MySQLAutoconfiguration {// ...}

Sljedeći obvezni korak je registracija klase kao kandidata za automatsku konfiguraciju, dodavanjem naziva klase ispod ključa org.springframework.boot.autoconfigure.EnableAutoConfiguration u standardnoj datoteci resources / META-INF / spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration = \ com.baeldung.autoconfiguration.MySQLAutoconfiguration

Ako želimo da naša klasa auto-konfiguracije ima prioritet nad ostalim kandidatima za automatsku konfiguraciju, možemo dodati @AutoConfigureOrder (Naređeno.HIGHEST_PRECEDENCE) bilješka.

Automatska konfiguracija dizajnirana je pomoću klasa i graha označenih s @Uvjetno napomene kako bi se mogla zamijeniti automatska konfiguracija ili njezini određeni dijelovi.

Imajte na umu da je automatska konfiguracija na snazi ​​samo ako automatski konfigurirani grah nije definiran u aplikaciji. Ako definirate svoj grah, tada će se poništiti zadani.

3.1. Razredni uvjeti

Razredni uvjeti nam to omogućuju navedite da će biti uključen grah za konfiguraciju ako je navedena navedena klasa koristiti @ConditionalOnClass napomena, ili ako je izostao predavanje koristiti @ConditionalOnMissingClass bilješka.

Odredimo da je naš MySQLConfiguration učitat će se samo ako klasa Izvor podataka je prisutan, u tom slučaju možemo pretpostaviti da će aplikacija koristiti bazu podataka:

@Configuration @ConditionalOnClass (DataSource.class) javna klasa MySQLAutoconfiguration {// ...}

3.2. Uvjeti graha

Ako želimo uključuju grah samo ako je navedeni grah prisutan ili ne, možemo koristiti @ConditionalOnBean i @ConditionalOnMissingBean bilješke.

Da bismo to ilustrirali, dodajmo znak entityManagerFactory bean u našu konfiguracijsku klasu i navedite da želimo da se taj bean kreira samo ako je bean pozvan izvor podataka je prisutan i ako grah zove entityManagerFactory još nije definirano:

@Bean @ConditionalOnBean (name = "dataSource") @ConditionalOnMissingBean javni LocalContainerEntityManagerFactoryBean entityManagerFactory () {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManaganFactory; em.setDataSource (dataSource ()); em.setPackagesToScan ("com.baeldung.autoconfiguration.example"); em.setJpaVendorAdapter (novi HibernateJpaVendorAdapter ()); if (AdditionalProperties ()! = null) {em.setJpaProperties (AdditionalProperties ()); } vratiti em; }

Konfigurirajmo i a actionManager grah koji će se učitati samo ako je grah tipa JpaTransactionManager još nije definirano:

@Bean @ConditionalOnMissingBean (type = "JpaTransactionManager") JpaTransactionManageractionManager (EntityManagerFactory entityManagerFactory) {JpaTransactionManageractionManager = novi JpaTransactionManager (); actionManager.setEntityManagerFactory (entityManagerFactory); vratiti transakcijuManager; }

3.3. Vlasnički uvjeti

The @ConditionalOnProperty anotacija se koristi navedite hoće li se učitati konfiguracija na temelju prisutnosti i vrijednosti svojstva Spring Environment.

Prvo, dodajmo izvornu datoteku svojstva za našu konfiguraciju koja će odrediti odakle će se svojstva čitati:

@PropertySource ("classpath: mysql.properties") javna klasa MySQLAutoconfiguration {// ...}

Možemo konfigurirati glavni Izvor podataka grah koji će se koristiti za stvaranje veza s bazom podataka na takav način da će se učitati samo ako se pozove svojstvo usemysql je prisutan.

Možemo koristiti atribut imaVrijednost za specificiranje određenih vrijednosti usemysql svojstvo koje se mora podudarati.

Definirajmo izvor podataka grah sa zadanim vrijednostima koji se povezuju s lokalnom bazom podataka koja se naziva myDb ako je usemysql svojstvo je postavljeno na lokalno:

@Bean @ConditionalOnProperty (name = "usemysql", havingValue = "local") @ConditionalOnMissingBean javni DataSource dataSource () {DriverManagerDataSource dataSource = novi DriverManagerDataSource (); dataSource.setDriverClassName ("com.mysql.cj.jdbc.Driver"); dataSource.setUrl ("jdbc: mysql: // localhost: 3306 / myDb? createDatabaseIfNotExist = true"); dataSource.setUsername ("mysqluser"); dataSource.setPassword ("mysqlpass"); vratiti dataSource; }

Ako je usemysql svojstvo je postavljeno na prilagođen, the izvor podataka bean će se konfigurirati pomoću vrijednosti prilagođenih svojstava za URL baze podataka, korisnika i lozinku:

@Bean (name = "dataSource") @ConditionalOnProperty (name = "usemysql", havingValue = "custom") @ConditionalOnMissingBean javni DataSource dataSource2 () {DriverManagerDataSource dataSource = novi DriverManagerDataSource (novi DriverManagerDataSource) dataSource.setDriverClassName ("com.mysql.cj.jdbc.Driver"); dataSource.setUrl (env.getProperty ("mysql.url")); dataSource.setUsername (env.getProperty ("mysql.user")! = null? env.getProperty ("mysql.user"): ""); dataSource.setPassword (env.getProperty ("mysql.pass")! = null? env.getProperty ("mysql.pass"): ""); vratiti dataSource; }

The mysql.svojstva datoteka će sadržavati usemysql svojstvo:

usemysql = lokalno

Ako je aplikacija koja koristi MySQLAutoconfiguration želi nadjačati zadana svojstva, sve što treba učiniti je dodati različite vrijednosti za mysql.url, mysql.korisnik i mysql.prolaz svojstva i usemysql = prilagođeno redak u mysql.svojstva datoteka.

3.4. Uvjeti resursa

Dodavanje @ConditionalOnResource napomena znači da konfiguracija će se učitati samo kada je prisutan navedeni resurs.

Definirajmo metodu tzv additionalProperties () koji će vratiti a Svojstva objekt koji sadrži svojstva hibernacije koja će se koristiti entityManagerFactory bean, samo ako je datoteka resursa mysql.svojstva je prisutan:

@ConditionalOnResource (resources = "classpath: mysql.properties") @Conditional (HibernateCondition.class) Svojstva additionalProperties () {Svojstva hibernateProperties = nova svojstva (); hibernateProperties.setProperty ("hibernate.hbm2ddl.auto", env.getProperty ("mysql-hibernate.hbm2ddl.auto")); hibernateProperties.setProperty ("hibernate.dialect", env.getProperty ("mysql-hibernate.dialect")); hibernateProperties.setProperty ("hibernate.show_sql", env.getProperty ("mysql-hibernate.show_sql")! = null? env.getProperty ("mysql-hibernate.show_sql"): "false"); return hibernateProperties; }

Možemo dodati specifična svojstva hibernacije mysql.svojstva datoteka:

mysql-hibernate.dialect = org.hibernate.dialect.MySQLDialect mysql-hibernate.show_sql = true mysql-hibernate.hbm2ddl.auto = create-drop

3.5. Prilagođeni uvjeti

Ako ne želimo koristiti bilo koji od uvjeta dostupnih u Spring Boot-u, također možemo definirajte prilagođene uvjete proširivanjem SpringBootCondition klase i nadjačavanje getMatchOutcome () metoda.

Stvorimo uvjet zvan HibernateCondition za naše additionalProperties () metoda koja će provjeriti je li a HibernateEntityManager razred je prisutan na putu predavanja:

statička klasa HibernateCondition proširuje SpringBootCondition {private static String [] CLASS_NAMES = {"org.hibernate.ejb.HibernateEntityManager", "org.hibernate.jpa.HibernateEntityManager"}; @Override public ConditionOutcome getMatchOutcome (ConditionContext context, AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition ("Hibernate"); vratiti Arrays.stream (CLASS_NAMES) .filter (className -> ClassUtils.isPresent (className, context.getClassLoader ())) .map (className -> ConditionOutcome .match (message.found ("class") .items (Style.NORMAL) , className))) .findAny () .orElseGet (() -> ConditionOutcome .noMatch (message.didNotFind ("class", "classes") .items (Style.NORMAL, Arrays.asList (CLASS_NAMES))))); }}

Tada možemo dodati uvjet na additionalProperties () metoda:

@Conditional (HibernateCondition.class) Svojstva additionalProperties () {// ...}

3.6. Uvjeti prijave

Možemo i mi navedite da se konfiguracija može učitati samo unutar / izvan web konteksta, dodavanjem @ConditionalOnWebApplication ili @ConditionalOnNotWebApplication bilješka.

4. Testiranje automatske konfiguracije

Stvorimo vrlo jednostavan primjer za testiranje naše automatske konfiguracije. Stvorit ćemo entitetnu klasu koja se zove MyUseri a MyUserRepository sučelje koje koristi Spring Data:

@Entity javna klasa MyUser {@Id private String email; // standardni konstruktor, getteri, postavljači}
javno sučelje MyUserRepository proširuje JpaRepository {}

Da bismo omogućili automatsku konfiguraciju, možemo koristiti jedan od @SpringBootApplication ili @EnableAutoConfiguration napomene:

@SpringBootApplication javna klasa AutoconfigurationApplication {javna statička void glavna (String [] args) {SpringApplication.run (AutoconfigurationApplication.class, args); }}

Dalje, napišimo a JUNIT test koji sprema a MyUser entitet:

@RunWith (SpringJUnit4ClassRunner.class) @SpringBootTest (classes = AutoconfigurationApplication.class) @EnableJpaRepositories (basePackages = {"com.baeldung.autoconfiguration.example"}) javni razred AutoconfigurationTest {@Autoworered @Test public void whenSaveUser_thenOk () {MyUser user = new MyUser ("[email protected]"); userRepository.save (korisnik); }}

Budući da nismo definirali svoje Izvor podataka konfiguracija, aplikacija će upotrijebiti automatsku konfiguraciju koju smo stvorili za povezivanje s a MySQL baza podataka nazvana myDb.

Niz veze sadrži createDatabaseIfNotExist = true svojstvo, tako da baza podataka ne mora postojati. Međutim, korisnik mysqluser ili onaj naveden kroz mysql.korisnik ako je prisutno, treba ga stvoriti.

Možemo provjeriti zapisnik aplikacija da vidimo je li MySQL koristi se izvor podataka:

web - 2017-04-12 00: 01: 33,956 [glavna] INFO o.s.j.d.DriverManagerDataSource - Učitani JDBC pokretački program: com.mysql.cj.jdbc.Driver

5. Onemogućavanje klasa automatske konfiguracije

Kad bismo htjeli izuzeti automatsku konfiguraciju iz učitavanja, mogli bismo dodati @EnableAutoConfiguration bilješka s isključiti ili excludeName atribut klasi konfiguracije:

@Configuration @EnableAutoConfiguration (exclude = {MySQLAutoconfiguration.class}) javna klasa AutoconfigurationApplication {// ...}

Druga opcija za onemogućavanje određenih automatskih konfiguracija je postavljanjem proljeće.autoconfigure.exclude svojstvo:

spring.autoconfigure.exclude = com.baeldung.autoconfiguration.MySQLAutoconfiguration

6. Zaključci

U ovom uputstvu pokazali smo kako stvoriti prilagođenu automatsku konfiguraciju Spring Boot. Puni izvorni kod primjera može se naći na GitHubu.

Test JUnit može se pokrenuti pomoću autokonfiguracija profil: mvn clean install -Pautoconfiguration.