眾所周知,Spring DI和Spring IOC是Spring Framework的核心概念。讓我們從org.springframework.beans.factory.annotation和org.springframework.context.annotation包中探索一些Spring核心注釋。我們經常將這些稱為“Spring核心注釋”,我們將在本文中對它們進行講解。
這是所有已知的Spring核心注釋的列表。
@Autowired
我們可以使用@Autowired注釋來標記Spring將要解析和注入的依賴關系。我們可以將這個注釋與構造函數,setter或字段注入一起使用
- 構造器注入
@RestController public class CustomerController { private CustomerService customerService; @Autowired public CustomerController(CustomerService customerService) { this.customerService=customerService; } }
- setter注入
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; @RestController public class CustomerController { private CustomerService customerService; @Autowired public void setCustomerService(CustomerService customerService) { this.customerService=customerService; } }
- 領域注入
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; @RestController public class CustomerController { @Autowired private CustomerService customerService; }
@Bean
- @Bean是方法級注釋,是XML元素的直接模擬。 注釋支持一些提供的屬性,例如init-method,destroy-method,auto-wiring和name。
- 您可以在
@Configuration
注解或@Component
注解類中使用@Bean
批注 - 以下是方法聲明的簡單示例
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.companyname.projectname.customer.CustomerService; import com.companyname.projectname.order.OrderService; @Configuration public class Application { @Bean public CustomerService customerService() { return new CustomerService(); } @Bean public OrderService orderService() { return new OrderService(); } }
- 上述配置等效於以下Spring XML:
<beans> <bean id="customerService"class="com.companyname.projectname.CustomerService"/> <bean id="orderService" class="com.companyname.projectname.OrderService"/> </beans>
@Qualifier
此注釋有助於微調基於注釋的自動布線。 可能存在這樣的情況:我們創建多個相同類型的bean,並且只想使用屬性連接其中一個bean。 這可以使用@ Qualifier
注釋以及 @Autowired
注釋來控制。
示例:考慮使用EmailService和SMSService類來實現單個MessageService接口
- 為多個消息服務實現創建MessageService接口。
public interface MessageService { public void sendMsg(String message); }
- 接下來,創建實現:EmailService和SMSService。
public class SMSService implements MessageService { public void sendMsg(String message) { System.out.println(message); } } public class EmailService implements MessageService { public void sendMsg(Stringmessage) { System.out.println(message); } }
- 這時候該看看 @Qualifier注釋的用法了
public interface MessageProcessor { public void processMsg(String message); } public class MessageProcessorImpl implements MessageProcessor { private MessageService messageService; // setter based DI @Autowired @Qualifier("emailService") public void setMessageService(MessageService messageService) { this.messageService=messageService; } // constructor based DI @Autowired public MessageProcessorImpl(@Qualifier("emailService")MessageService messageService) { this.messageService = messageService; } public void processMsg(String message) { messageService.sendMsg( message); } }
@Required
@Required
注釋是一個方法級注釋,並應用於bean的setter方法。此注釋僅指示必須將setter方法配置為在配置時使用值依賴注入。
例如,對setter方法的 @Required
標記了我們想要通過XML填充的依賴項:
@Required void setColor(String color){ this.color= color; } <bean class="com.javaguides.spring.Car"> <property name = "color" value="green"/> </bean>
否則,將拋出BeanInitializationException。
@Value
Spring @Value
注釋用於為變量和方法參數指定默認值。我們可以使用@Value 注釋來讀取Spring環境變量以及系統變量 。Spring @Value
注釋也支持SpEL。讓我們看一下使用@Value 注釋的一些示例 。
示例:我們可以使用@Value 注釋為類屬性指定默認值 。
@Value("Default DBConfiguration") private String defaultName;
該 @Value 注釋參數可以是只有字符串,但春天嘗試將其轉換為指定的類型。以下代碼將正常工作,並將布爾值和整數值分配給變量。
@Value("true") private boolean defaultBoolean; @Value("10") private int defaultInt;
這演示了Spring @Value
- Spring環境變量
@Value("${APP_NAME_NOT_FOUND}") private String defaultAppName;
接下來,使用 @Value
注釋分配系統變量 。
@Value("${java.home}") private String javaHome; @Value("${HOME}") private String homeDir;
Spring @Value – SpEL
@Value("#{systemProperties['java.home']}") private String javaHome;
@DependsOn
該 @DependsOn
注釋可以強制的Spring IoC容器中的bean,它是由注釋之前初始化一個或多個bean @DependsOn
注釋。
所述 @DependsOn
注釋可以在直接或間接地注釋與任何類使用 @Component
或與所述注解的方法 @Bean
。
示例:讓我們創建 FirstBean
和 SecondBean
類。在此示例中, SecondBean
在 bean
之前初始化 FirstBean
。
public class FirstBean{ @Autowired private SecondBean secondBean; } public class SecondBean { public SecondBean() { System.out.println("SecondBean Initialized via Constuctor"); } }
基於配置類在Java中聲明上述bean。
@Configuration public class AppConfig { @Bean("firstBean") @DependsOn(value={"secondBean"}) public FirstBean firstBean() { return new FirstBean(); } @Bean("secondBean") public SecondBean secondBean() { return new SecondBean(); } }
@Lazy
默認情況下,Spring IoC容器在應用程序啟動時創建並初始化所有單例bean。我們可以通過使用 @Lazy
注釋來防止單例bean的這種預初始化 。
所述 @Lazy 注釋可以在任何類中使用,與直接或間接地注釋 @Component
或與所述注解的方法 @Bean
。
示例:考慮我們有兩個bean - FirstBean 和 SecondBean。在此示例中,我們將FirstBean 使用 @Lazy
注釋顯式加載。
public class FirstBean{ public void test() { System.out.println("Method of FirstBean Class"); } } public class SecondBean{ public void test(){ System.out.println("Method of SecondBean Class"); } }
基於配置類在Java中聲明上述bean。
@Configuration public class AppConfig { @Lazy( value =true) @Bean public FirstBean firstBean() { return new FirstBean(); } @Bean public SecondBean secondBean() { return new SecondBean (); } }
我們可以看到,bean secondBean 由Spring容器初始化,而bean firstBean 則被顯式初始化。
@Lookup
注釋的方法 @Lookup
告訴Spring在我們調用它時返回方法返回類型的實例。
@Primary
我們使用 @Primary
當存在多個相同類型的bean時,我們使用它 給bean更高的優先級。
@Component @Primary class Car implements Vehicle {} @Component class Bike implements Vehicle {} @Component class Driver { @Autowired Vehicle vehicle; } @Component class Biker { @Autowired @Qualifier( "bike") Vehicle vehicle; }
@Scope
我們使用@ Scope注釋來定義 @Component
類的范圍或 @Bean
定義。 它可以是單例,原型,請求,會話,globalSession或某些自定義范圍。 舉個例子:
@Component @Scope(value= ConfigurableBeanFactory.SCOPE_SINGLETON) public class TwitterMessageService implements MessageService { } @Component @Scope(value =ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class TwitterMessageService implements MessageService { }
@Profile
如果我們希望Spring僅在特定配置文件處於活動狀態時使用 @Component
類或 @Bean
方法,我們可以使用 @Profile
標記它。 我們可以使用注釋的value參數配置配置文件的名稱:
@Component @Profile("sportDay") class Bike implements Vehicle { }
@Import
該 @Import
注釋指示一個或多個 @Configuration
類進口。
例如:在基於Java的配置中,Spring提供了 @Import
注釋,允許從另一個配置類加載 @Bean
定義。
@Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public B b() { return new B (); } }
現在,在實例化上下文時,不需要同時指定ConfigA類和ConfigB類,只需要顯式提供ConfigB。
@ImportResource
Spring提供了一個 @ImportResource
注釋,用於將 applicationContext.xml
文件中的bean加載到ApplicationContext中。
例如:考慮我們在類路徑上有 applicationContext.xml
Spring bean配置XML文件。
@Configuration @ImportResource( {"classpath*:applicationContext.xml"}) public class XmlConfiguration { }
@PropertySource
該 @PropertySource 注釋提供了一種方便的聲明性機制,用於添加 PropertySource Spring的Eenvironment以與@Configuration類一起使用 。
例如,我們從文件config.properties文件中讀取數據庫配置,並使用Environment 將這些屬性值設置為 DataSourceConfig類。
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration @PropertySource("classpath:config.properties") public class ProperySourceDemo implements InitializingBean { @Autowired Environment env; @Override public void afterPropertiesSet()throws Exception { setDatabaseConfig(); } private void setDatabaseConfig() { DataSourceConfig config = new DataSourceConfig(); config.setDriver( env.getProperty("jdbc.driver")); config.setUrl(env.getProperty("jdbc.url")); config.setUsername(env.getProperty("jdbc.username")); config.setPassword(env.getProperty("jdbc.password")); System.out.println(config.toString()); } }
@PropertySources
我們可以使用此批注指定多個 @PropertySource
配置:
@PropertySources( { @PropertySource("classpath:config.properties"), @PropertySource("classpath:db.properties") }) public class AppConfig { //... }