通过注解装配Bean
1.使用@Component装配Bean
//value代表bean的id,可以简写("role"),也可以不写,就默认类名,首字母小写 @Component(value="role") public class Role { //@Value代表值的注入,那如何注入对象? @Value("1") private int id; @Value("role_name_1") private String roleName; @Value("role_note_1") private String note; //setter getter }
1.1使用@ComponentScan扫描当前包的Bean
//默认是扫描当前包的路径,pojo包名和它保持一致才能扫描,否则是没有的 @ComponentScan public class Config { }
使用@ComponentScan扫描指定包及类的Bean
//@ComponentScan(basePackageClasses= {Role.class,RoleServiceImpl.class}) //@ComponentScan(basePackages= {"test"}) @ComponentScan(basePackages= {"test"},basePackageClasses= {Role.class,RoleServiceImpl.class})
一个@Component只会生成一个对象,多个就会生成多个对象,通常使用basePackages比较直观,可读性好,但涉及大量重构的工程,包名会反复修改,用basePackageClasses会更好。
1.2 自动装配——@Autowired
@Value是简单的值的注入,而@Autowired是让spring根据类型去寻找定义的Bean然后将其注入。
自动装配的歧义性(@Primary和@Qualifier)
当一个接口有多个实现类,按类型就失效了,IOC容器会糊涂,不知道注入哪个。这是就用到@Primary和@Qualifier。
@Primary:优先注入
@Qualifier:指定具体的某一个类注入,显然@Qualifier更准确。
2.使用@Bean装配Bean
当引入第三方包时无法修改源码来添加@Component,也就是无法使用@Component,就可以使用@Bean。@Bean可以注解到方法上,并且将方法返回的对象作为Spring的Bean,存放在IOC容器中。
@Bean还可以以注解的方式实现自定义的Bean的初始化方法和销毁方法。
@Bean(name="juiceMaker",initMethod="myInit",destroyMethod="myDestroy")
3.装配的混合使用
在自己的工程中多使用注解,而对于第三方包或者服务的类,尽量使用XML方式,好处是可以减少对第三方包或者服务的理解,而直接使用,更加简洁明朗。
@ImportResource:可以配置多个XML文件,从而引入相对应的Bean。
@ImportResource({"classpath:spring-dataSource.xml"}) public class ApplicationConfig{ }
@Import:注入配置类
@Import({ApplicationConfig2.class,ApplicationConfig3.class}) public class ApplicationConfig{ }
<import resource="spring-datasource.xml"/>
而xml文件加载java配置类,目前spring是不支持的
4.加载属性(properties)文件
@PropertySource:
@PropertySource(value={"classpath:spring-dataSource.properties"},ignoreResourceNotFound=true) public class ApplicationConfig{ }
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(ApplicationConfig.class); String url=ctx.getEnvironment().getProperty("jdbc.database.url"); System.out.println(url);
使用引入属性文件的配置:@Value(“${jdbc.database.url}”),当然要先在配置文件里进行占位符配置:
public PropertySourcePlaceholderConfigurer propertySourcePlaceholderConfigurer(){ return new PropertySourcePlaceholderConfigurer(); }
使用xml方式加载属性文件:
方法一
<context:property-placeholder ignore-resource-not-found="true" location="classpath:database-config.properties"/>
方法二:配置多个属性文件时更加直观
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!--字符串数组,可配置多个属性文件 -->
<property name="locations">
<array>
<value>classpath:database-config.properties</value>
<value>classpath:log4j.properties</value>
</array>
</property>
<property name="ignoreResourceNotFound" value="false" />
</bean>
5.条件化装配bean
@Conditional:
例如:@Conditional({DataSourceCondition.class}),然后在DataSourceCondition.class中去配置条件。
6.Bean的作用域
单例(singleton)
原型(prototype)
会话(session)
请求(request)
如何设置:比如@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
7.使用spring表达式(Spring EL)
更为灵活的注入方式,也更为强大。
功能:
1.使用Bean的id来引用Bean
//通过beanName获取bean,然后注入 @Value("#{role}") private Role role;
//获取指定对象的属性id @Value("#{role.id}") private Long id; //调用bean的getNote方法,获取角色名称 //这里toString是为了返回为空时抛出异常,如果不想抛出异常,可以"#{role.getNote()?.toString()}",是空的就不调用toString()方法 @Value("#{role.getNote().toString()}") private String note;