整个项目结构r如下:
org.springframework
spring-context
4.3.12.RELEASE
在测试类中的运行结果为:基于spring4.0注解开发,零配置:
@Configuration
到目前为止,您已经看到了如何使用XML配置文件来配置Spring bean。 如果您对XML配置感到满意,那么实际上并不需要学习如何继续使用基于Java的配置,因为您将使用任何可用配置获得相同结果。
基于Java的配置选项使您可以在不使用XML的情况下编写大部分Spring配置,但需要借助本章中介绍的少数基于Java的注释。
使用@Configuration注解一个类表明该类可以被Spring IoC容器用作bean定义的来源。 @Bean注解告诉Spring,用@Bean注解的方法将返回一个应该在Spring应用程序上下文中注册为bean的对象。 最简单的@Configuration类可能如下 :
@Configuration
public class MainConfig {
//给容器中注册一个bean;类型为返回值的类型,id默认用方法名作为id
@Bean(name = "person")
public Person person01(){
return new Person("张三",18);
}
}
上面的代码将等同于下面的xml配置
在这里,方法名用@bean作为bean ID进行注释,并且它创建并返回实际的bean,你的配置类可以有一个或多个@bean的声明。一旦定义类配置类,您就可以使用注解Configapplicationtent来加载并将它们提供给spring容器
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Person person =(Person) context.getBean("person");
System.out.println(person);
注入bean依赖关系
当@bean彼此依赖时,表示依赖性就像拥有一个bean方法调用一个bean方法一样简单
@Service
public class BookService {
@Autowired
private Person person;
public void print(){
System.out.println(person.getName()+"今年"+person.getAge()+"岁");
}
}
@Scope
在Spring中,bean的范围用于决定那些类型的bean实例应该从Spring容器返回给调用者。
支持四种类型的bean作用域:
singleton(单例) -ioc容器启动的时候会调用方法创建对象,每一个Spring ioc容器返回同一个bean的实例。
prototype(多例)-ioc容器启动的时候不会创建对象,每次调用的时候才会调用方法创建对象,即每一次调用
时创建一个新的be'an实例。
request-同一个请求创建一个实例,即每一个HTTP请求返回一个实例。
session-同一个session创建一个实例,即么一个HTTP session返回同一个实例。
singleton vs prototype
下面是一个示例,向您展示bean scope:singleton和prototype之间的区别:
/***
* scope:指定注解的组件/bean使用的范围的名称。
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
* singleton:单实例的(默认值)
* prototype:多实例的
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*
*
*/
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean()
public Person person(){
return new Person("里斯",20);
}
@Test
public void test01(){
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
String [] names = context.getBeanDefinitionNames();
for (String name:names) {
System.out.println("======="+name);
}
Person person = (Person)context.getBean("person");
Person person01 = (Person)context.getBean("person");
System.out.println(person == person01);
}
@Lazy
指知否要对bean进行懒惰初始化,可用于任何直接或者间接使用@Component注释的 @Component 或者使用@Bean注释的方法。如果此注释不存在于@Component或者@Bean定义上,则会在spring ioc容器启动的时候初始化bean。如果存在并设置true,则@Bean或者@Compoent将不会
被初始化,直到被另一个be'an应用挥着BeanFactory检索才会创建实例。如果存在并设置为false,那么bean将会在spring ioc启动的时候被beanFactory实例化。
如果Lazy存在于@Configuration类中,则表明该@Configuration中的所有@Bean方法都被延迟初始化。如果@Configuration类中的@Bean方法为@Lazy,则表示覆盖defaultlazy行为,并且该bean在被引用的时候才会初始化。
除了它在组件初始化方面的作用之外,这个注解还可以放在标注有Autowired
或Inject
注入点上:在这种情况下,它会导致为所有受影响的依赖项创建一个延迟解析代理,作为使用ObjectFactory
的替代方法或Provider
。
@Conditional
表示当所有指定的条件匹配时,组件仅适用于注册。
如果@Configuration
类标记为@Conditional
,则与@Conditional
所有@Bean
方法, @Import
@Bean
标注和@ComponentScan
标注都将受条件限制。
@Conditional({
WindowCondition.class
})
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",60);
}
public class WindowCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String systemName = environment.getProperty("os.name");
if(systemName.contains("Windows")){
return true;
}
return false;
}
}
只有当windouwCondition metches方法返回true的时候容器启动的时候才会初始化person
@Import
import注解允许从另一个配置类装载bean定义
zhau装载一个或多个要导入的@Configuration
类。
提供了与Spring XML中的
元素等效的功能。 允许导入@Configuration
类, ImportSelector
和ImportBeanDefinitionRegistrar
实现,以及常规组件类(从4.2开始;类似于AnnotationConfigApplicationContext.register(java.lang.Class>...)
)。
在@Configuration
类中声明的@Bean
定义应该使用@Autowired
注入来访问。 可以自动装配bean本身,或者声明该bean的配置类实例可以是自动装配的。 后一种方法允许在@Configuration
类方法之间进行明确的,可以在元注释中声明。如果需要导入XML或其他非@Configuration
bean定义资源,请改为使用@ImportResource
注释。
@Configuration
@Import(CDConfig.class) //导入CDConfig的配置
public class CDPlayerConfig {
@Bean(name = "cDPlayer")
public CDPlayer cdPlayer(CompactDisc compactDisc) {
/*这里会注入CompactDisc类型的bean
这里注入的这个bean是CDConfig.class中的CompactDisc类型的那个bean*/
return new CDPlayer(compactDisc);
}
@ImportResource
指示一个或多个包含要导入的bean定义的资源。
像@Import
一样,这个注解提供了类似于Spring XML中的
元素的功能。 它通常用于设计由AnnotationConfigApplicationContext
引导的@Configuration
类,但是其中仍然需要某些XML功能(如命名空间)。