原文出處:https://www.cnblogs.com/duanxz/p/7493276.html
從Spring3.0,@Configuration
用於定義配置類,可替換xml配置文件,被註解的類內部包含有一個或多個被@Bean註解的方法,這些方法將會被AnnotationConfigApplicationContext
或AnnotationConfigWebApplicationContext
類進行掃描,並用於構建bean定義,初始化Spring容器。
注意:@Configuration
註解的配置類有如下要求:
@Configuration
不可以是final類型;
@Configuration
不可以是匿名類;
嵌套的configuration必須是靜態類。
一、用@Configuration
加載spring
1.1、@Configuration
配置spring並啓動spring容器
1.2、@Configuration
啓動容器+@Bean註冊Bean
1.3、@Configuration
啓動容器+@Component註冊Bean
1.4、使用 AnnotationConfigApplicationContext
註冊 AppContext 類的兩種方法
1.5、配置Web應用程序(web.xml中配置AnnotationConfigApplicationContext
)
二、組合多個配置類
2.1、在@configuration
中引入spring的xml配置文件
2.2、在@configuration
中引入其它註解配置
2.3、@configuration
嵌套(嵌套的Configuration必須是靜態類)
三、@EnableXXX
註解
四、@Profile
邏輯組配置
五、使用外部變量
@Configuation加載Spring方法
@Configuation註解一個類配置應用上下文
用@Configuation
註解一個類,這個類相當於Spring容器的應用上下文(xml)
配置類
package test;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
}
相當於,這個xml應用上下文
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
測試
package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class test {
public static void main(String[] args){
AbstractApplicationContext context
= new AnnotationConfigApplicationContext(BeansContainer.class);
}
}
結果
@Configuration啓動容器+@Bean註冊Bean,@Bean下管理bean的生命週期
@Bean標註在方法上(返回某個實例的方法),等價於spring的xml配置文件中的,作用爲:註冊bean對象
bean類:
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
@Bean("person")
@Scope("prototype")
public Person createPerson(){
return new Person();
}
}
配置類
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
@Bean("person")
@Scope("prototype")
public Person createPerson(){
return new Person();
}
}
測試
package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class test {
public static void main(String[] args){
AbstractApplicationContext context
= new AnnotationConfigApplicationContext(BeansContainer.class);
Person person = context.getBean("person",Person.class);
}
}
結果
注:
(1)、@Bean
註解在返回實例的方法上,如果未通過@Bean
指定bean的名稱,則默認與標註的方法名
相同;
(2)、@Bean
註解默認作用域爲單例singleton
作用域,可通過@Scope(“prototype”)
設置爲原型作用域;
(3)、既然@Bean
的作用是註冊bean對象,那麼完全可以使用@Component、@Controller、@Service、@Ripository
等註解註冊bean,當然需要配置@ComponentScan
註解進行自動掃描。
@Bean下管理bean的生命週期
可以使用基於 Java 的配置來管理 bean 的生命週期。@Bean 支持兩種屬性,即 initMethod
和destroyMethod
,這些屬性可用於定義生命週期方法。在實例化 bean 或即將銷燬它時,容器便可調用生命週期方法。生命週期方法也稱爲回調方法,因爲它將由容器調用。使用 @Bean
註釋註冊的 bean 也支持 JSR-250
規定的標準 @PostConstruct
和 @PreDestroy
註釋。如果您正在使用 XML 方法來定義 bean,那麼就應該使用 bean 元素來定義生命週期回調方法。以下代碼顯示了在 XML 配置中通常使用 bean 元素定義回調的方法。
bean類
package test;
public class Person {
private String name;
public Person(){
System.out.println("創建Person對象");
System.out.println(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init(){
System.out.println("this is init()");
}
public void destroy(){
System.out.println("this is destroy");
}
}
配置類
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
@Bean(name = "person",initMethod = "init",destroyMethod = "destroy")
@Scope("prototype")
public Person createPerson(){
return new Person();
}
}
測試
package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class test {
public static void main(String[] args){
AbstractApplicationContext context
= new AnnotationConfigApplicationContext(BeansContainer.class);
Person person = context.getBean("person",Person.class);
Person person2 = context.getBean("person",Person.class);
}
}
結果
分析:
結果中的1:表明initMethod
生效
結果中的2:表明@Scope("prototype")
生效
@Configuration啓動容器+@Component註冊Bean
bean類:
package test;
import org.springframework.stereotype.Component;
@Component("p")
public class Person {
private String name;
public Person(){
System.out.println("創建Person對象");
System.out.println(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init(){
System.out.println("this is init()");
}
public void destroy(){
System.out.println("this is destroy");
}
}
配置類
package test;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan(basePackages = "test")
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
/**
@Bean(name = "person",initMethod = "init",destroyMethod = "destroy")
@Scope("prototype")
public Person createPerson(){
return new Person();
}*/
}
測試
package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class test {
public static void main(String[] args){
AbstractApplicationContext context
= new AnnotationConfigApplicationContext(BeansContainer.class);
Person person = context.getBean("p",Person.class);
}
}
@Component("beanName")
指定bean的名字,便於取用bean
使用 AnnotationConfigApplicationContext 註冊 AppContext 類的兩種方法
配置類的註冊方式是將其傳遞給 AnnotationConfigApplicationContext 構造函數
// @Configuration註解的spring容器加載方式,用AnnotationConfigApplicationContext替換ClassPathXmlApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
//獲取bean
TestBean tb = (TestBean) context.getBean("testBean");
tb.sayHello();
AnnotationConfigApplicationContext 的register 方法傳入配置類來註冊配置類
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppContext.class)
}
配置Web應用程序(web.xml中配置AnnotationConfigApplicationContext)
過去,您通常要利用 XmlWebApplicationContext
上下文來配置 Spring Web 應用程序,即在 Web 部署描述符文件 web.xml 中指定外部 XML 上下文文件的路徑。XMLWebApplicationContext
是 Web 應用程序使用的默認上下文類。以下代碼描述了 web.xml 中指向將由 ContextLoaderListener
監聽器類載入的外部 XML 上下文文件的元素。
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>sampleServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
...
</web-app>
現在,您要將 web.xml 中的上述代碼更改爲使用 AnnotationConfigApplicationContext
類。切記,XmlWebApplicationContext
是 Spring 爲 Web 應用程序使用的默認上下文實現,因此您永遠不必在您的web.xml 文件中顯式指定這個上下文類。現在,您將使用基於 Java 的配置,因此在配置 Web 應用程序時,需要在web.xml 文件中指定 AnnotationConfigApplicationContext
類。上述代碼將修改如下:
<web-app>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.
support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
demo.AppContext
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>sampleServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.
support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
</servlet>
...
</web-app>
以上修改後的 web.xml 現在定義了 AnnotationConfigWebApplicationContext
上下文類,並將其作爲上下文參數和 servlet 元素的一部分。上下文配置位置現在指向 AppContext
配置類。這非常簡單。下一節將演示 bean 的生命週期回調和範圍的實現。
@Configuation總結
@Configuation
等價於 <Beans></Beans>
@Bean
等價於<Bean></Bean>
@ComponentScan
等價於<context:component-scan base-package="com.dxz.demo"/>
組合多個配置類
在@configuration中引入spring的xml配置文件
配置類
package test;
import org.springframework.context.annotation.*;
import test2.Config;
@Configuration
@ImportResource("classpath:xspringmvc-servlet.xml")
@ComponentScan(basePackages = "test")
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
}
xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 支持的其中一個屬性,支持的最大文件大小,以字節爲單位 -->
<property name="maxUploadSize" value="100000"/>
</bean>
<bean
</beans>
這裏很遺憾,我想添加以上bean時,會報錯,可能跟依賴有關係,導入自己的bean是可以的。
在@configuration中引入其它註解配置
配置類
package test;
import org.springframework.context.annotation.*;
import test2.Config;
@Configuration
@Import(Config.class)
@ComponentScan(basePackages = "test")
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
}
package test2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
public Config(){
System.out.println("啓動Config容器");
}
@Bean
public Student student(){
return new Student();
}
}
@configuration嵌套(嵌套的Configuration必須是靜態類)
通過配置類嵌套的配置類,達到組合多個配置類的目的。但注意內部類必須是靜態類
package test;
import org.springframework.context.annotation.*;
import test2.Config;
@Configuration
@ComponentScan(basePackages = "test")
public class BeansContainer {
public BeansContainer(){
System.out.println("啓動spring容器");
}
@Configuration
static class innerBeansContainer{
public innerBeansContainer(){
System.out.println("啓動BeansContainer容器");
}
@Bean
public boss boss(){
return new boss();
}
}
}