spring ioc---基於註解的配置(context包,@Configuration,@Bean,etc)
註解 | 釋義 |
@Configuration | 宣告一個基於java註解的配置類物件.一般和@Bean組合使用,當然根據不同的場景,可配合其他多種註解使用. 原始碼(部分)文件:Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime. |
@Bean | 使用此標註,表示為容器註冊一個bean,相當於xml配置檔案中的bean標籤. 原始碼(部分)文件:Indicates that a method produces a bean to be managed by the Spring container. |
@ComponentScan | 使用此標註,表示開啟註解掃描,相當於xml配置檔案中的<context:component-scan>標籤. 原始碼(部分)文件:Configures component scanning directives for use with @Configuration classes. Provides support parallel with Spring XML's <context:component-scan> element. |
@ComponentScans[✘] | 聚合多個註解掃描器,相當於xml配置檔案中配置多行開啟註解掃描器的標籤.其預設值儲存的是ComponentScan型別的陣列. 原始碼(部分)文件:Container annotation that aggregates several ComponentScan annotations. |
@Primary | 當存在同一類物件多個bean配置的時候,獲取bean例項不明確的時候,設定首選bean. 原始碼(部分)文件:Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value. |
@Scope | 配置bean的作用域,相當於xml配置檔案中bean標籤的scope屬性. 另,在web包中,有針對不同作用域的建議配置註解,例如@RequestScope,@SessionScope,e.g. 原始碼(部分)文件:When used as a type-level annotation in conjunction with @Component,@Scope indicates the name of a scope to use for instances of the annotated type.When used as a method-level annotation in conjunction with @Bean,@Scopeindicates the name of a scope to use for the instance returned from the method. |
@Lazy | 設定配置的bean為懶載入.等價於xml配置檔案中bean標籤中的lazy-init的屬性. 原始碼(部分)文件:Indicates whether a bean is to be lazily initialized. |
@Description | 設定容器中配置bean的描述資訊,從版本4.3新增註解.提取描述資訊的時候,使用BeanDefinition類的方法.原始碼(部分)文件:Adds a textual description to bean definitions derived from |
@Role | 定義容器中bean的身份,不常用,通常bean的等級為0.類物件BeanDefinition中內建的對映常量.原始碼(部分)文件:Indicates the 'role' hint for a given bean. |
@Conditional | 設定容器註冊bean的條件限制,滿足容器則註冊,否則不予註冊.定製的條件限制需要實現Condition介面實現.註解@Profile就是借用此介面實現的.原始碼(部分文件):Indicates that a component is only eligible for registration when all specified conditions match. |
@Profile[✘] | Indicates that a component is eligible for registration when one or more specified profiles are active. |
@DependsOn[✘] | 注入依賴關係不直接的bean使用,相當於xml配置檔案中bean標籤的depends-on屬性.原始碼(部分)文件:Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean. Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean's initialization. |
@Filter[✘] | 一般配合註解@ComponentScan使用.原始碼(部分)文件:Declares the type filter to be used as an include filter or exclude filter. |
@Import[✘] | Indicates one or more |
@ImportResource[✘] | Indicates one or more resources containing bean definitions to import. |
@PropertySource[✘] | Annotation providing a convenient and declarative mechanism for adding a |
@PropertySources[✘] | Container annotation that aggregates several |
@EnableAspectJAutoProxy[✘] | Enables support for handling components marked with AspectJ's |
@EnableLoadTimeWeaving[✘] | Activates a Spring LoadTimeWeaver for this application context, available as a bean with the name "loadTimeWeaver", similar to the |
@EnableMBeanExport[✘] | Enables default exporting of all standard |
@EnableSrpingConfigured[✘] | Signals the current application context to apply dependency injection to non-managed classes that are instantiated outside of the Spring bean factory (typically classes annotated with the |
備忘,表格中註解後面沒有新增`[✘]`,是程式碼測試的部分註解.
測試bean的類物件
package siye;
public class MemberCls
{
public void init()
{
System.out.println("bean_init...");
}
}
容器的配置類
package siye;
import java.util.Map;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Role;
import org.springframework.context.annotation.Scope;
import org.springframework.core.type.AnnotatedTypeMetadata;
/*
* 1,註解configuration:標註此類是基於java註解的配置類,
* 相當於xml配置檔案中的beans標籤.
* 另,此類的配置資訊可通過ApplicationContext的實現類註冊.
* 2,註解bean:標註此方法用來定義一個bean,
* 相當於xml配置檔案的bean標籤.
* 3,註解componentScan:開啟註解掃描
* 相當於xml配置檔案中的<context:component-scan>標籤.
* 另版本4.3開始,新增註解componentScans,其預設值型別是
* 註解componentScan陣列,即聚合多個註解掃描器.
* 相當於xml配置檔案中定義多行對等的標籤.
*
* 一般在基於java註解的配置類中,建議使用configuration和bean的組合方式.
* 當然也存在其他的配置方式.
*/
@Configuration
@ComponentScan("siye")
public class ConfigClass
{
/*
* 註解primary
* 當容器對同一類物件定義兩個以上的bean標識的時候,
* 容器獲取該類物件例項的時候未提供明確依據,
* 使用註解primary,即可設定該bean未首選的
*/
@Primary
@Bean("annoPrimary")
public String annoPrimary()
{
return new String();
}
/*
*
* 註解scope
* 1,預設值value(即scopeName),有四個候選值,
* 即singleton,prototype,requestScope,sessionScope
* 可使用ConfigurableBeanFactory和WebApplicationContext
* 中內建的常量.
* 2,值proxyMode
* 儲存型別為ScopedProxyMode,即等價於xml配置檔案中的標籤:
* <aop:scoped-proxy/>
* 3,版本4.3開始,此註解擴充套件了兩個建議註解,即註解requestScope
* 和註解sessionScope.
*
* 當只是用預設值配置的時候,相當於bean標籤中的scope屬性,
* 管理bean的作用域.
*/
@Bean("annoScope")
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public String annoScope()
{
return new String();
}
/*
* 註解lazy
* 配置bean是否懶載入
* 值value的預設值true
*/
@Bean(name = "annoLazy", initMethod = "init")
@Lazy
public MemberCls annoLazy()
{
return new MemberCls();
}
/*
* 註解description
* 對容器中管理的bean的描述資訊,配合componpent和bean註解使用.
* 最低版本要求4.0
*/
@Bean("annoDesc")
@Description("this's_test_anno_description")
public String annoDesc()
{
return new String();
}
/*
* 註解role
* 標註容器中存在的bean的身份.
* 可使用BeanDefinition中的常量表示,
* 0,表示使用者建立的bean
* 1,支援容器正常執行的配置bean
* 2,表示後臺容器工作必備的bean
*/
@Bean("annoRole")
@Role(value = BeanDefinition.ROLE_APPLICATION)
public String annoRole()
{
return new String();
}
/*
* 註解conditional
* 條件限制,滿足條件,則讓容器註冊該bean,不滿足的話,
* 什麼也不做.
* 補充註解,profile就是使用該特性實現的.
*
* 若註解bean的name值不是annoConditional,
* 則容器不會註冊該bean.
*/
@Bean("annoConditional")
@Conditional(MyConditional.class)
public String annoConditional()
{
return new String("test_annoConditional");
}
}
/*
* 定製條件限制
* 使用註解bean,且其name值是annoConditional,
* 即允許容器註冊該bean.
* 否則不予註冊.
*/
class MyConditional implements Condition
{
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata)
{
if (context.getEnvironment() != null)
{
if (metadata.getAnnotationAttributes(Bean.class.getName()) != null)
{
Map<String, Object> map =
metadata.getAnnotationAttributes(Bean.class.getName());
String[] arr = (String[]) map.get("name");
int index = 0;
while (true)
{
if ("annoConditional".equals(arr[index]))
{
return true;
}
index++;
if (index >= arr.length)
{
return false;
}
}
}
}
return false;
}
}
測試類
package siye;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class UnitTest
{
private AnnotationConfigApplicationContext context;
@Before
public void init()
{
context = new AnnotationConfigApplicationContext();
context.register(ConfigClass.class);
context.refresh();
}
@Test
public void testPrimary()
{
// 若未設定首選的bean,則丟擲異常NoUniqueBeanDefinitionException
String obj = context.getBean(String.class);
System.out.println(obj.hashCode());
}
@Test
public void testScope()
{
// 驗證註解scope
String bean0 = context.getBean("str1", String.class);
String bean1 = context.getBean("str1", String.class);
System.out.println(bean0 == bean1);
}
@Test
public void testLazy()
{
System.out.println(context);
// 呼叫次方法的時候,才初始化該bean,並回調初始化方法.
// context.getBean("annoLazy", MemberCls.class);
}
@Test
public void testDesc()
{
BeanDefinition beanDefinition = context.getBeanDefinition("annoDesc");
String result = beanDefinition.getDescription();
System.out.println(result);
}
@Test
public void testRole()
{
int result = context.getBeanDefinition("annoRole").getRole();
System.out.println(result);
}
@Test
public void testConditional()
{
String obj = context.getBean("annoConditional", String.class);
System.out.println(obj);
}
@After
public void destroy()
{
if (context != null)
{
context.close();
}
}
}