Spring 使用介绍(九)—— 零配置(二)
三、Bean定义
1、开启bean定义注解支持
开启注解支持须添加以下配置项:
<context:component-scan base-package="cn.matt"/>
2、支持bean定义的注解
Spring自带@Component注解及扩展@Repository、@Service、@Controller,用于定义bean,如图所示
上述注解默认的bean名字是以小写开头的类名(不包含包名),bean的名字也可由注解的value属性明确指定
@Service public class ServiceAImpl { ... } // 默认bean名称:serviceAImpl
@Service("myService") public class ServiceAImpl { ... } // 明确指定
3、自定义扩展
可在@Component、@Repository、@Service、@Controller基础上,定义自己的注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface MyService { String value() default ""; }
注意,value属性可指定bean名称,与spring自带注解相同
4、细粒度控制Bean定义扫描
<context:component-scan>标签支持细粒度控制Bean定义扫描
<context:component-scan base-package="" resource-pattern="**/*.class" name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator" use-default-filters="true" annotation-config="true"> <context:include-filter type="aspectj" expression=""/> <context:exclude-filter type="regex" expression=""/> </context:component-scan>
属性说明:
- base-package:表示扫描注解类的开始位置,即将在指定的包中扫描,其他包中的注解类将不被扫描,默认将扫描所有类路径。
- resource-pattern:表示扫描注解类的后缀匹配模式,即“base-package+resource-pattern”将组成匹配模式用于匹配类路径中的组件,默认后缀为“**/*.class”,即指定包下的所有以.class结尾的类文件。
- name-generator:默认情况下的Bean标识符生成策略,默认是AnnotationBeanNameGenerator,其将生成以小写开头的类名(不包括包名),也可以自定义自己的标识符生成策略。
- use-default-filters:默认为true表示过滤@Component、@ManagedBean、@Named注解的类,如果改为false默认将不过滤这些默认的注解来定义Bean,即这些注解类不能被过滤到,即不能通过这些注解进行Bean定义。
- annotation-config:表示是否自动支持注解实现Bean依赖注入,默认支持,如果设置为false,将关闭支持注解的依赖注入,需要通过<context:annotation-config/>开启。
过滤器说明:
- <context:include-filter>:表示过滤到的类将被注册为Spring管理Bean。
- <context:exclude-filter>:表示过滤到的类将不被注册为Spring管理Bean,它比<context:include-filter>具有更高优先级。
- type:表示过滤器类型,目前支持注解类型、类类型、正则表达式、aspectj表达式过滤器,当然也可以自定义自己的过滤器,实现org.springframework.core.type.filter.TypeFilter即可。
- expression:表示过滤器表达式。
过滤器使用示例:
<!-- 类 --> <context:include-filter type="assignable" expression="cn.matt.TestBean1"/> <!-- 注解 --> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> <!-- 正则表达式 --> <context:exclude-filter type="regex" expression="cn\.matt\.TestBean2*"/>
Spring MVC中的典型配置:
<!-- spring-context.xml中的配置 --> <context:component-scan base-package="com.wind.pac" use-default-filters="true"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- spring-mvc.xml中的配置 --> <context:component-scan base-package="com.wind.pac" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" /> </context:component-scan>
5、其他配置
i)@Lazy:定义Bean将延迟初始化
@Component("component") @Lazy(true) public class TestCompoment { ... }
ii)@Scope:定义Bean作用域,默认单例
@Component("component") @Scope("singleton") public class TestCompoment { ... }
iii)@Qualifier:指定限定描述符,对应于基于XML配置中的<qualifier>标签
@Component("component") @Qualifier("component") public class TestCompoment { ... }
iv)@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Component("component") @Primary public class TestCompoment { ... }
四、Java类替换配置文件
1、简单示例
简单类
public class Girl { @Autowired private String name; public String getName() { return name; } }
配置元数据的java类
@Configuration public class MyConfig { @Bean public String myGirl() { return "qqm"; } @Bean public Girl girl() { return new Girl(); } }
测试
public class ConfigTest { @Test public void test() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); Assert.assertTrue(StringUtils.equals("qqm", context.getBean("myGirl", String.class))); Girl girl = context.getBean(Girl.class); Assert.assertTrue(StringUtils.equals("qqm", girl.getName())); } }
2、详细介绍
i)@Configuration
- 通过@Configuration注解的类将被作为配置类使用,表示在该类中将定义Bean配置元数据
- @Configuration是@Component注解的扩展,因此@Configuration注解的类本身也是一个Bean
- @Configuration注解的类不能是final的,且应该有一个默认无参构造器
- 使用AnnotationConfigApplicationContext 指定配置类时,@Configuration注解可省略
ii)@Bean
@Bean(name={}, autowire=Autowire.NO, initMethod="", destroyMethod="")
- name:指定Bean的名字,可有多个,第一个作为Id,其他作为别名
- autowire:自动装配,默认no表示不自动装配该Bean
- initMethod和destroyMethod:指定Bean的初始化和销毁方法
- 对于依赖注入,可使用赋值的方式注入(如同创建一个实体并赋值),也可使用注解的方式注入(不需要开启注解,如上例)
iii)引入其他配置
引入基于java方式的配置类
@Configuration @Import({MyConfig2.class}) public class MyConfig { ... }
引入基于XML的配置
@Configuration @ImportResource("classpath:spring-context.xml") public class ApplicationContextConfig { ... }
3、XML配置中引入Java方式的配置
XML开启bean定义支持,并扫描到@Configuration配置类,即可引入
参考:
第十二章 零配置 之 12.3 注解实现Bean定义 ——跟我学spring3
第十二章 零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3