控制权翻转,对象的创建、初始化、销毁全部交由Spring管理;通过动态组件注册、bean对象初始化管理、依赖注入、
bean对象初始化前后进行次要业务组装实现
@Configuration修饰的类就相当于一个配置文件
@Configuration//相当于配置文件
public class ApplicationConfig {
//表示xml里面的bean标签value是ID值,这里value中可以是多个值逗号隔开,任何一个值都可以表示这个对象
@Bean(value={"t1","t2"})
public Test test1(){
return new Test();
}
}
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(ApplicationConfig.class);
System.out.println("Spring 容器启动了。。。");
Test t =(Test)context.getBean("t1");
//这个注解专用于单例模式bean对象,此时bean对象不会在spring容器启动时被创建的,
//只有在一个用户来访时才会被创建
@Lazy
@Bean
public Test test(){
return new Test();
}
(1)可以指定初始化和销毁的方法
//bean类
public class Test {
public void init(){
System.out.println("实列化对象被初始化");
}
public void destory(){
System.out.println("实列化对象被销毁");
}
}
@Configuration//相当于配置文件
public class ApplicationConfig {
@Bean(initMethod="init",destroyMethod="destroy")
public Test test(){
return new Test();
}
}
(2)让bean类文件同时实现InitializingBean接口与DisposableBean接口.根据这两个接口提供的监听方法,来监听当前类的bean的实例化时机和销毁时机
public class Test2 implements InitializingBean,DisposableBean{
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("Test2对象被销毁");
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("Test2对象初始化");
}
}
(3)在类中指定方法上添加这两个注解,来指定监听bean对象被实例化和销毁的时机@PreDestroy& @PostConstruct
public class Test3 {
public Test3(){
System.out.println("构造方法被调用");
}
@PostConstruct
public void init(){
System.out.println("Test3对象被初始化");
}
@PreDestroy
public void destroy(){
System.out.println("Test3对象被销毁");
}
}
可以将某些类排除在Spring容器之外(excludeFilters属性)
可以将某些类添加到Spring容器之内 (includeFilters属性)
FilterType:扫描过滤策略
@ComponentScan(value="com.test.beans",excludeFilters={
@Filter(type=FilterType.ANNOTATION,
value={Controller.class,Service.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,
value={Test01.class}
})
//扫描com.test.beans包下类,排除注解@Controller的类,根据指定类型排除类Test01
@Configuration//相当于配置文件
public class ApplicationConfig {
}
//
@ComponentScan(value="com.test.beans",useDefaultFilters=false,includeFilters={
@Filter(type=FilterType.ANNOTATION,
value={Controller.class,Service.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,
value={Test01.class}
})
//扫描com.test.beans包下类去掉默认的过滤规则,扫描@Controller@Service注解的类,根据指定类型扫描类Test01
@Configuration//相当于配置文件
public class ApplicationConfig {
}
自定义扫描策略如下
/**
**自定义扫描策略
**实现TypeFilter接口.然后重写TypeFilter接口中match方法
**/
public class CustomerFilter implements TypeFilter {
public boolean match(MetadataReader arg0, MetadataReaderFactory arg1) throws IOException {
//获取当前bean关联的注解类型
AnnotationMetadata annotationMetadata = arg0.getAnnotationMetadata();
String classname = annotationMetadata.getClassName();//获取类名
//当前类上修饰的注解类型全路劲名
Set annotationTypes = annotationMetadata.getAnnotationTypes();
System.out.println();
for(String str:annotationTypes){
System.out.println(str+"3543545");
}
//获取当前bean类的类型信息
ClassMetadata classMetadata = arg0.getClassMetadata();
String cn =classMetadata.getClassName();
System.out.println("---"+cn);
if(cn.contains("er")){
System.out.println("满足要求得类"+cn);
return true;
}
return false;
}
}
@ComponentScan(value="com.test.beans",useDefaultFilters=false,
includeFilters={
@Filter(type=FilterType.CUSTOM,
value={CustomerFilter.class})
})
@Configuration//相当于配置文件
public class ApplicationConfig2 {
}
@Scope("prototype"):标识多例模式创建对象
@Scope("singleton"):标识单例例模式创建对象
Conditionnal注解中使用一个使用一个数组,这个数组存放的就是自定义判断条件,开发人员可以通过实现Condition接口,来定义自判断条件.
@Conditional({自定义条件类型.class})
//linux系统下才实列化对象
public class LinuxCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String systemName = context.getEnvironment().getProperty("os.name");
if(systemName.contains("Linux")){
return true;
}
return false;
}
}
//windows系统下才实列化对象
public class WindowsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String systemName = context.getEnvironment().getProperty("os.name");
if(systemName.contains("windows")){
return true;
}
return false;
}
}
//配置类
@Configuration
public class ApplicationConfig {
@Conditional({LinuxCondition.class})
@Bean
public Test test(){
return new Test();
}
}
//测试类
public class TestMain {
public static void main(String[] args) {
//1.获得Spring容器对象
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(ApplicationConfig.class);
//2.获得在Spring容器已经注册bean对象,可以发现在windows上运行Test对象未被实列化
String beanNames[]= context.getBeanDefinitionNames();
for(String beanName:beanNames){
System.out.println(beanName);
}
}
}
//指定JdbcConfig类加入Spring IOC作为配置类
@Import(value="com.test.bean.JdbcConfig.class")
@Configuration//相当于配置文件
public class ApplicationConfig {
}
或者通过实现ImportSelector自定义选择器
//自定义查询器
public class MyImport implements ImportSelector{
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//添加两个类
String array[] = {"com.test.beans.Test1","com.test.beans.Test2"};
return array;
}
}
//配置文件
@Import(MyImport.class)
@Configuration
public class ApplicationConfig {
}
//实现FactoryBean接口
public class MyFactoryBean implements FactoryBean{
//获取实例对象
public Test1 getObject() throws Exception {
// TODO Auto-generated method stub
return new Test1();
}
//获取对象类型
public Class> getObjectType() {
// TODO Auto-generated method stub
return Test1.class;
}
//此方法不重写默认是单列
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
//配置类
@Configuration
public class ApplicationConfig {
@Bean
public MyFactoryBean getMyFactoryBean(){
return new MyFactoryBean();
}
}
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
@Autowired注解的时候默认是@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败;
@Autowired(required=false)表示忽略当前要注入的bean,一般再微服务开发过程中,因为模块分开,可能实现类是在另外一个模块中,此时需要用到这个,否则会装配失败报错
@Primary//表示优先实列话
@service
public class UserService implements IUserService {
}
@Resource其实跟@AutoWired一样的功能,只是提供方不一样,@AutoWired是spring框架中提供的注解,而@Resource是javax.annotation包 提供,JSR250 规范实现
注入方式
@Autowired优先按照类型byType注入
@Resource默认按byName自动注入,也提供按照byType 注入,两个属性name和type
当找不到与名称匹配的 bean 时才按照类型进行装配,但是需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配
在javax.inject包 中,JSR330 规范实现的,与@Resource即@Autoware一样,根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named; 可以作用对象在setter方法、构造方法、字段上
@Inject标注通过optional参数来定义注入的接口是否需要注入的实现类,默认情况必须显示声明注入接口的实现。
给基本类型和 String 类型注入值 ,可以使用占位符获取属性文件中的值
@Value(“${name}”)//name 是 properties 文件中的 key
private String name;
加载 properties 配置文件,编写在类上面 ,相当于 context:property-placeholder 标签
属性value[]:用于指定properties文件路径,如果在类路径下,需要写上classpath
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
}
BeanPostProcessor是一个接口,主要用于在bean对象初始化前后,做一些辅助功能
接口中包含的方法
postProcessBeforeInitialization:bean被初始化之前工作
postProcessAfterInitialization:被初始化之后工作
//定义自己的process
public class MyBeanPostProcess implements BeanPostProcessor{
public MyBeanPostProcess(){
System.out.println("构造方法被调用");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("初始化前"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("初始化后"+beanName);
return bean;
}
}
//加入的bean容器中
@Configuration//相当于配置文件
public class ApplicationConfig3 {
@Bean
public MyBeanPostProcess myBeanPostProcess(){
return new MyBeanPostProcess();
}
}
//测试
public class TestMain3 {
public static void main(String[] args) {
//1.获得Spring容器对象
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(ApplicationConfig3.class);
System.out.println("Spring 容器启动了。。。");
//此时容器已启动初始化bean对象会执行MyBeanPostProcess中方法
}