צור תצורה אוטומטית מותאמת אישית עם Spring Boot

1. סקירה כללית

במילים פשוטות, התצורה האוטומטית של Spring Boot מייצגת דרך להגדיר באופן אוטומטי יישום Spring בהתבסס על התלות הקיימת בדרך הכיתה.

זה יכול להפוך את הפיתוח למהיר וקל יותר על ידי ביטול הצורך בהגדרת שעועית מסוימת הכלולה בשיעורי התצורה האוטומטית.

בחלק הבא, אנו נסתכל על יצירת התצורה האוטומטית של Spring Boot המותאמת אישית שלנו.

2. תלות Maven

נתחיל עם התלות הדרושה לנו:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.2.RELEASE mysql mysql-connector-java 8.0.19 

ניתן להוריד את הגרסאות העדכניות ביותר של אביב-אתחול-התחל-נתונים-jpa ו- mysql-connector-java מ Maven Central.

3. יצירת תצורה אוטומטית מותאמת אישית

כדי ליצור תצורה אוטומטית מותאמת אישית, עלינו ליצור מחלקה המסומנת כ- @תְצוּרָה ולרשום אותו.

בואו ניצור תצורה מותאמת אישית עבור a MySQL מקור מידע:

@Configuration מחלקה ציבורית MySQLAutoconfiguration {// ...}

השלב החובה הבא הוא רישום הכיתה כמועמד לתצורה אוטומטית, על ידי הוספת שם הכיתה מתחת למפתח org.springframework.boot.autoconfigure.EnableAutoConfiguration בקובץ הסטנדרטי משאבים / META-INF / spring.factories:

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

אם אנו רוצים שמחלקת התצורה האוטומטית שלנו תקבל עדיפות על פני מועמדים אחרים לתצורה אוטומטית, אנו יכולים להוסיף את @ AutoConfigureOrder (הורה. HIGHEST_PRECEDENCE) ביאור.

תצורה אוטומטית מתוכננת באמצעות מחלקות ושעועית המסומנים ב @מותנה הערות כך שניתן להחליף את התצורה האוטומטית או את החלקים הספציפיים שלה.

שים לב כי התצורה האוטומטית תקפה רק אם השעועית המוגדרת אוטומטית אינה מוגדרת ביישום. אם אתה מגדיר את השעועית שלך, ברירת המחדל תיפסל.

3.1. תנאי כיתה

תנאי הכיתה מאפשרים לנו ציין כי שעועית תצורה תיכלל אם קיימת מחלקה מסוימת משתמש ב @ConditionalOnClass ביאור, או אם שיעור נעדר משתמש ב @ConditionalOnMissingClass ביאור.

בואו נפרט כי שלנו MySQLConfiguration יוטען רק אם הכיתה מקור מידע קיים, ובמקרה זה נוכל להניח שהיישום ישתמש במסד נתונים:

@Configuration @ConditionalOnClass (DataSource.class) מחלקה ציבורית MySQLAutoconfiguration {// ...}

3.2. תנאי שעועית

אם אנחנו רוצים לכלול שעועית רק אם קיימת שעועית מסוימת או לא, אנחנו יכולים להשתמש ב- @ConditionalOnBean ו @ConditionalOnMissingBean ביאורים.

כדי להדגים זאת, בואו להוסיף entityManagerFactory שעועית למחלקת התצורה שלנו, וציין שאנו רוצים שעועית זו תיווצר רק אם שעועית התקשרה מקור מידע קיים ואם שעועית נקראה entityManagerFactory עדיין לא מוגדר:

@Bean @ConditionalOnBean (name = "dataSource") @ConditionalOnMissingBean ציבור LocalContainerEntityManagerFactoryBean entityManagerFactory () {LocalContainerEntityManagerFactoryBean em = חדש LocalContainerEntityManagerFactoryBean (); em.setDataSource (dataSource ()); em.setPackagesToScan ("com.baeldung.autoconfiguration.example"); em.setJpaVendorAdapter (חדש HibernateJpaVendorAdapter ()); אם (additionalProperties ()! = null) {em.setJpaProperties (additionalProperties ()); } להחזיר אותם; }

בואו גם להגדיר א transactionManager שעועית שתוטען רק אם שעועית מסוג JpaTransactionManager עדיין לא מוגדר:

@Bean @ConditionalOnMissingBean (type = "JpaTransactionManager") JpaTransactionManager transactionManager (EntityManagerFactory entityManagerFactory) {JpaTransactionManager transactionManager = JpaTransactionManager חדש (); transactionManager.setEntityManagerFactory (entityManagerFactory); TransactionManager החזר; }

3.3. תנאי רכוש

ה @ConditionalOnProperty ההערה רגילה ל ציין אם תצורה תוטען על בסיס נוכחות וערך של מאפיין Spring Environment.

ראשית, בואו להוסיף קובץ מקור נכס לתצורה שלנו שיקבע מהיכן יקראו המאפיינים:

@PropertySource ("classpath: mysql.properties") מחלקה ציבורית MySQLAutoconfiguration {// ...}

אנחנו יכולים להגדיר את הראשי מקור מידע שעועית שתשמש ליצירת חיבורים למסד הנתונים באופן שהוא ייטען רק אם מאפיין קורא usemysql נוכח.

אנו יכולים להשתמש בתכונה בעל ערך כדי לציין ערכים מסוימים של usemysql נכס שיש להתאים.

בואו נגדיר את מקור מידע שעועית עם ערכי ברירת מחדל שמתחברים למסד נתונים מקומי שנקרא myDb אם ה usemysql נכס מוגדר ל מְקוֹמִי:

@Bean @ConditionalOnProperty (name = "usemysql", havingValue = "local") @ConditionalOnMissingBean DataSource dataSource () {DriverManagerDataSource dataSource = DriverManagerDataSource חדש (); dataSource.setDriverClassName ("com.mysql.cj.jdbc.Driver"); dataSource.setUrl ("jdbc: mysql: // localhost: 3306 / myDb? createDatabaseIfNotExist = true"); dataSource.setUsername ("mysqluser"); dataSource.setPassword ("mysqlpass"); להחזיר dataSource; }

אם ה usemysql נכס מוגדר ל המותאם אישית, ה מקור מידע שעועית תוגדר באמצעות ערכי מאפיינים מותאמים אישית עבור כתובת האתר, המשתמש והסיסמה של מסד הנתונים:

@Bean (name = "dataSource") @ConditionalOnProperty (name = "usemysql", havingValue = "custom") @ConditionalOnMissingBean DataSource publicSource2 () {DriverManagerDataSource dataSource = 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"): ""); להחזיר dataSource; }

ה mysql.properties הקובץ יכיל את usemysql תכונה:

usemysql = מקומי

אם יישום המשתמש ב- MySQLA תצורה אוטומטית רוצה לעקוף את מאפייני ברירת המחדל, כל שעליו לעשות הוא להוסיף ערכים שונים עבור ה- mysql.url, mysql.user ו mysql.pass נכסים ו usemysql = מותאם אישית קו ב mysql.properties קוֹבֶץ.

3.4. תנאי משאבים

הוספת ה- @ConditionalOnResource פירוש ההערה הוא כי התצורה נטענת רק כאשר קיים משאב מוגדר.

בואו נגדיר שיטה שנקראת נוסף נכסים () שיחזיר א נכסים אובייקט המכיל מאפיינים ספציפיים למצב שינה שישמש את ה- entityManagerFactory שעועית, רק אם קובץ המשאב mysql.properties נוכח:

@ConditionalOnResource (resources = "classpath: mysql.properties") @Conditional (HibernateCondition.class) מאפיינים additionalProperties () {Properties hibernateProperties = מאפיינים חדשים (); 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"): "שקר"); החזר מאפייני שינה; }

אנו יכולים להוסיף את המאפיינים הספציפיים למצב שינה mysql.properties קוֹבֶץ:

mysql-hibernate.dialect = org.hibernate.dialect.MySQLDialect mysql-hibernate.show_sql = נכון mysql-hibernate.hbm2ddl.auto = create-drop

3.5. תנאים מותאמים אישית

אם איננו רוצים להשתמש באף אחד מהתנאים הקיימים ב- Spring Boot, נוכל גם לעשות זאת להגדיר תנאים מותאמים אישית על ידי הרחבת ה- SpringBootCondition מעמד ועוקף את getMatchOutcome () שיטה.

בואו ניצור תנאי שנקרא מצב שינה בשביל שלנו נוסף נכסים () שיטה שתוודא אם א HibernateEntityManager הכיתה נמצאת בשביל הכיתה:

מחלקה סטטית HibernateCondition מרחיבה את SpringBootCondition {מחרוזת סטטית פרטית [] CLASS_NAMES = {"org.hibernate.ejb.HibernateEntityManager", "org.hibernate.jpa.HibernateEntityManager"}; @Override תנאי ציבוריOutcome getMatchOutcome (הקשר ConditionContext, מטא נתונים מסוג AnnotatedTypeMetadata) {MessageMessage.Builder message = ConditionMessage.forCondition ("מצב שינה"); החזר 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)))); }}

אז נוכל להוסיף את התנאי ל- נוסף נכסים () שיטה:

@Conditional (HibernateCondition.class) מאפיינים additionalProperties () {// ...}

3.6. תנאי הגשת בקשה

אנחנו יכולים גם ציין כי ניתן לטעון את התצורה רק בתוך / מחוץ להקשר אינטרנט, על ידי הוספת ה- @ תנאי יישום אוֹ @ConditionalOnNotWeb יישום ביאור.

4. בדיקת התצורה האוטומטית

בואו ניצור דוגמה פשוטה מאוד לבדיקת התצורה האוטומטית שלנו. ניצור מחלקת ישויות שנקראת MyUser, ו MyUserRepository ממשק המשתמש בנתוני אביב:

@Entity מחלקה ציבורית MyUser {@Id דוא"ל מחרוזת פרטי; // קונסטרוקטור סטנדרטי, גטרים, סטרים}
ממשק ציבורי MyUserRepository מרחיב את JpaRepository {}

כדי לאפשר תצורה אוטומטית, נוכל להשתמש באחת מה- @ SpringBootApplication אוֹ @EnableAutoConfiguration ביאורים:

@SpringBootApplication מחלקה ציבורית ציבורי אוטומטי הגדרת יישום {ציבורי ריק ריק סטטי (String [] args) {SpringApplication.run (AutoconfigurationApplication.class, args); }}

לאחר מכן, בוא נכתוב א JUnit מבחן שחוסך א MyUser יֵשׁוּת:

@RunWith (SpringJUnit4ClassRunner.class) @SpringBootTest (classes = AutoconfigurationApplication.class) @EnableJpaRepositories (basePackages = {"com.baeldung.autoconfiguration.example"}) תצוגה אוטומטית מחלקה ציבורית AutoconfigurationTest {@Autowired פרטי MyUserepository; @Test ציבורי בטל כאשרSaveUser_thenOk () {משתמש משתמש שלי = משתמש חדש שלי ("[מוגן באמצעות דוא"ל]"); userRepository.save (user); }}

מכיוון שלא הגדרנו את שלנו מקור מידע תצורה, היישום ישתמש בתצורה האוטומטית שיצרנו כדי להתחבר ל- MySQL מסד נתונים שנקרא myDb.

מחרוזת החיבור מכילה את createDatabaseIfNotExist = true מאפיין, כך שמסד הנתונים לא צריך להתקיים. עם זאת, המשתמש mysqluser או זה שצוין באמצעות ה- mysql.user נכס אם הוא קיים, צריך ליצור אותו.

אנו יכולים לבדוק את יומן היישומים כדי לראות שה- MySQL נעשה שימוש במקור נתונים:

אינטרנט - 12-04-2017 00: 01: 33,956 [ראשי] INFO o.s.j.d DriverManagerDataSource - מנהל התקן JDBC טעון: com.mysql.cj.jdbc.Driver

5. השבתת שיעורי תצורה אוטומטית

אם היינו רוצים אל תכלול את טעינת התצורה האוטומטית, נוכל להוסיף את @EnableAutoConfiguration ביאור עם לא לכלול אוֹ excludeName תכונה לשיעור תצורה:

@Configuration @EnableAutoConfiguration (exclude = {MySQLAutoconfiguration.class}) תצורה אוטומטית מחלקה ציבורית יישום {// ...}

אפשרות נוספת להשבית תצורות אוטומטיות ספציפיות היא על ידי הגדרת spring.autoconfigure.exclude תכונה:

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

6. מסקנות

במדריך זה הראינו כיצד ליצור תצורה אוטומטית של אתחול האביב המותאם אישית. קוד המקור המלא של הדוגמה נמצא ב- GitHub.

ניתן להריץ את מבחן JUnit באמצעות ה- תצורה אוטומטית פּרוֹפִיל: mvn נקי להתקין - תצורה אוטומטית.