הערה על @Configuration בקובץ הגדרה של האפליקציה בספרינג

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

Spring @Configuration

האננוטציה Spring @Configuration מאפשרת לנו להשתמש באננוטציות עבור הזרמת תלות. בואו נבין איך ליצור מחלקות Spring Configuration. בואו ניצור מחלקת חלון פשוטה.

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

לפני שנשתמש בכל מחלקות המסגרת של Spring, נצטרך להוסיף את התלות שלה לפרוייקט Maven.

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

עכשיו בואו ניצור את מחלקת הגדרת ההגדרה של Spring.

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

בואו נכתוב מחלקה פשוטה ונגדיר את מחלקת הגדרת ההגדרה שלנו.

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

אם תפעיל את היישום שנמצא למעלה, הוא יפיק פלט כמו זה:

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

שימו לב שספרינג מטען פוליים להקשת שלו טרם שביקשנו אותם. מטרת זאת היא לוודא שכל הפוליים מוגדרים כהלכה ושהיישום יכשל מהר אם משהו לא בסדר. גם ctx.refresh() חייבת להיקרא, אחרת נקבל שגיאה הבאה כאשר ננסה לקבל פוליים מההקשה.

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

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

מה יקרה אם נסיר את ה-@Configuration הערה?

מה יקרה אם נסיר את ה-@Configuration הערה ממחלקת MyConfiguration. תגלו שהתוכנית עדיין תעבוד כמצופה ופוליים של ספרינג יירשמו ויתקבלו כמחלקות סינגלטון. אך במקרה זה, אם נקרא לשיטת myBean() אז זה יהיה קריאה רגילה לשיטת ג'אווה ונקבל מופע חדש של MyBean והוא לא יישאר כסינגלטון. כדי להוכיח את הנקודה זו, בואו נגדיר פוליים נוספים שישתמשו במופע של MyBean.

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

מחלקת ההגדרות של ספרינג המעודכנת שלנו היא:

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

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

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

לכן MyBean לא נשמרת כעת, נכון לא נשמרת, עכשיו בואו נסמן את MyConfiguration עם האנוטציה @Configuration שוב ונפעיל את מחלקת MySpringApp. הפעם הפלט יהיה דומה למה שלמעלה.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

כך שזה טוב יותר להשתמש באנוטציית @Configuration עם מחלקות הגדרה כדי לוודא שמנוע הקפצה שלנו מתנהג כפי שרוצים. אם אתה לא רוצה להשתמש באנוטציית @Configuration מסיבות מוזרות כלשהן, עדיין ניתן ליצור את מחלקת ההגדרה שלנו באמצעות שאיבת השיטה myBean() ולהשתמש במשתנה אינסטנס של MyBean המוגדר דרך האנוטציה @Autowired. משהו דומה לקוד למטה יעבוד גם.

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

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

ניתן להוריד את קוד הדוגמה מהמאגר שלנו ב- GitHub Repository.

Source:
https://www.digitalocean.com/community/tutorials/spring-configuration-annotation