1. @Configuration, @Bean

@Configuration该注解就是用来告诉spring这是配置类

@Bean该注解是用来注册一个bean。类型是返回值的类型,ID默认是用方法名作为ID的;可以在注解中指定ID,@Bean("person")

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//MainConfig.class是配置类
Person bean = applicationContext.getBean(Person.class);

以上注解主要是用来取代了配置文件application.xml中对bean的定义

2. @ComponentScan

该注解用于包扫描,主要是取代了下面的配置。主要扫描标记有以下注解的:@Controller、@Service、@Repository,@Component

<context:component-scan base-package="com.atguigu" use-default-filters="false"></context:component-scan>

属性一:excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件

属性二:includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件;使用该注解需要在配置文件中添加use-default-filters="false",而在注解中,我们需要useDefaultFilters = false;

Java8中@ComponentScan是可以重复使用的,而且也可以使用@ComponentScans注解

@ComponentScans(
value = {
@ComponentScan(value="com.atguigu",includeFilters = {
@ComponentScan.Filter(type= FilterType.ANNOTATION,classes={Controller.class})
/* @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),
@Filter(type= FilterType.CUSTOM,classes={MyTypeFilter.class})*/
},useDefaultFilters = false)
}
)

3. FilterType

FilterType.ANNOTATION:按照注解

FilterType.ASSIGNABLE_TYPE:按照给定的类型;

FilterType.ASPECTJ:使用ASPECTJ表达式

FilterType.REGEX:使用正则指定

FilterType.CUSTOM:使用自定义规则

4. @scope

prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;

singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿。

5. @Lazy

单实例bean:默认在容器启动的时候创建对象;

懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

6.@Conditional

按照一定的条件进行判断,满足条件给容器中注册bean

@Conditional(LinuxCondition.class) 在类中进行条件判断 只有满足条件返回true时才会进行相应的操作,否则不会执行下面的代码。

7. @Import

@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})

@Import导入组件,id默认是组件的全类名

ImportSelector:返回需要导入的组件的全类名数组;自定义一个MyImportSelector实现ImportSelector接口。

    //返回值,就是到导入到容器中的组件全类名
//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//方法不要返回null值,可以返回空的数组
return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
}

ImportBeanDefinitionRegistrar:手动注册bean到容器中;自定义MyImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口。

/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所有需要添加到容器中的bean;调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//全类名
boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
if(definition && definition2){
//指定Bean定义信息;(Bean的类型,Bean。。。)
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个Bean,指定bean名
registry.registerBeanDefinition("rainBow", beanDefinition);
}
}

8. 工厂bean

自定义工厂bean实现spring的接口FactoryBean

1)默认获取到的是工厂bean调用getObject创建的对象,而不是工厂bean本身;

//工厂Bean获取的是调用getObject创建的对象  获取的是color bean对象
Object bean2 = applicationContext.getBean("colorFactoryBean");

2)要获取工厂Bean本身,我们需要给id前面加一个&

Object bean4 = applicationContext.getBean("&colorFactoryBean");

9. @bean的声明周期配置类

1)初始化的一些配置

1.1)、指定初始化和销毁方法;

通过@Bean指定init-method和destroy-method;

@Bean(initMethod="init",destroyMethod="detory")

1.2)、通过让Bean实现InitializingBean(定义初始化逻辑),

DisposableBean(定义销毁逻辑);

1.3)、可以使用JSR250;

@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法

@PreDestroy:在容器销毁bean之前通知我们进行清理工作

1.4)、BeanPostProcessor【interface】:bean的后置处理器;

在bean初始化前后进行一些处理工作;

postProcessBeforeInitialization:在初始化之前工作

postProcessAfterInitialization:在初始化之后工作

2)bean的生命周期:

2.1)构造(对象创建)

	单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象

2.2)BeanPostProcessor.postProcessBeforeInitialization

2.3)初始化:对象创建完成,并赋值好,调用初始化方法。。。

2.4)BeanPostProcessor.postProcessAfterInitialization

2.5)销毁:

	单实例:容器关闭的时候
多实例:容器不会管理这个bean;容器不会调用销毁方法;

3)BeanPostProcessor原理

遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization

  3.1)populateBean(beanName, mbd, instanceWrapper);//给bean进行属性赋值
3.2)initializeBean
{
3.3)
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
3.4)
invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
3.5)
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

3)Spring底层对BeanPostProcessor的使用

bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;

10.@Value @PropertySource

1)、基本数值

@Value("张三")

2)、可以写SpEL; #{}

@Value("#{20-2}")

3)、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)---大括号中写的是配置文件中的key。

//使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部的配置文件以后使用${}取出配置文件的值
@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MainConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}

@Value("${person.nickName}")
private String nickName;

也可以通过以下的方式获取配置文件中值

ConfigurableEnvironment environment = applicationContext.getEnvironment();
String property = environment.getProperty("person.nickName");
System.out.println(property);

11. 自动装配

Spring利用依赖注入DI,完成对IOC容器中各个组件赋值;

1-->@Autowired 自动注入--spring的

1)默认按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
2)如果找到多个相同类型的组件,在将属性的名称作为ID去容器中查找applicationContext.getBean("bookDao2")
@Autowired
private BookDao bookDao2;---这里的bookDao2
3)@Qualifier("bookDao"):使用@Qualifier指定需要装配的id,而不是属性名;
4)自动装配默认一定要将属性赋值好,没有就会报错可以使用@Autowired(required=false);在没有的情况下也不会报错
5)@Primary:让Spring进行自动装配的时候,默认使用首选的bean;也可以使用@Qualifier指定需要装配的bean的名字
1.1-->@Autowired

@Autowired可以标注在构造器,参数,方法,属性上;都是从容器中获取组件的值

1)标注在方法位置

    //@Autowired
//标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值;
//方法使用的参数,自定义类型的值从ioc容器中获取
public void setCar(Car car) {
this.car = car;
}

2)标注在构造器位置--如果组件只有一个有参构造器,这个有参构造器的 @Autowired可以省略,参数位置的组件还是可以从容器中自动获取

//默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
//构造器要用的组件,都是从容器中获取
@Autowired
public Boss(Car car){
this.car = car;
System.out.println("Boss...有参构造器");
}
2-->@Resource 自动注入--Java规范

默认是按照属性名称注入的@Resource(name="bookDao2") 不指定名字就是属性的名字。他是Java规范中的,它不支持@Primary和@Autowired(required=false)

3-->@Inject 自动注入--Java规范

它的功能和Autowired的是一样的,但是需要导入依赖包,其次他没有@Autowired(required=false)功能

4-->自定义组件 注入到bean中

如果自定义组件想要使用spring容器底层的一些组件,如applicationContext,BeanFactory...;自定义组件实现XXXAware;在创建对象的时候会调用规定的方法注入相关的组件---将spring底层的组件装配到自定义的bean中

XXXAware的功能都是使用XXXProcessor来处理的。

@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub
System.out.println("传入的ioc:"+applicationContext);
this.applicationContext = applicationContext;
}
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
System.out.println("当前bean的名字:"+name);
}
//StringValueResolver重要
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
// TODO Auto-generated method stub
String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
System.out.println("解析的字符串:"+resolveStringValue);
}
}
5-->@Profile 自动装配

Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

1)加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境

@Profile("default")

2)@Profile写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效.

即写在配置类上的@Profile中的属性必须在需要激活的环境中存在,然后按照需要激活的环境来加载bean

3)没有标注环境标识的bean在任何环境下都是加载的;

方式一:(test是指@Profile中ID值)
使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test
方式二:(不能使用有参构造器启动)
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
//1、创建一个applicationContext
//2、设置需要激活的环境
applicationContext.getEnvironment().setActiveProfiles("test","dev");
//3、注册主配置类
applicationContext.register(MainConfigOfProfile.class);
//4、启动刷新容器
applicationContext.refresh(); String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
for (String string : namesForType) {
System.out.println(string);
} // Yellow bean = applicationContext.getBean(Yellow.class);
// System.out.println(bean);
applicationContext.close();

12. 小结

组件添加:++@Import @Conditional++ @Configuration @Bean @ComponentScan @scope @Lazy @Controller @Service @Repository @Component @Primary 工厂模式

组件赋值:@Value @PropertySource @PropertySources @Autowired )@Qualifier @Resource @Inject @Profile

组件注入:方法参数,构造器注入,applicationContextAware(xxxAware)

spring注解开发-IOC的更多相关文章

  1. Annotation(三)——Spring注解开发

    Spring框架的核心功能IoC(Inversion of Control),也就是通过Spring容器进行对象的管理,以及对象之间组合关系的映射.通常情况下我们会在xml配置文件中进行action, ...

  2. spring注解开发中常用注解以及简单配置

    一.spring注解开发中常用注解以及简单配置 1.为什么要用注解开发:spring的核心是Ioc容器和Aop,对于传统的Ioc编程来说我们需要在spring的配置文件中邪大量的bean来向sprin ...

  3. 浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含自定义扫描组件.自定义导入组件.手动注册组件.自动注入方法和参数.使用Spring容器底层组件等 配置 @Confi ...

  4. 浅尝Spring注解开发_Bean生命周期及执行过程

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...

  5. 浅尝Spring注解开发_AOP原理及完整过程分析(源码)

    浅尝Spring注解开发_AOP原理及完整过程分析(源码) 浅尝Spring注解开发,基于Spring 4.3.12 分析AOP执行过程及源码,包含AOP注解使用.AOP原理.分析Annotation ...

  6. Spring注解开发_Spring容器创建概述

    浅尝Spring注解开发_Spring容器创建概述 浅尝Spring注解开发,基于Spring 4.3.12 概述Spring容器创建的过程,包括12个方法的执行 浅尝Spring注解开发_自定义注册 ...

  7. 浅尝Spring注解开发_Servlet3.0与SpringMVC

    浅尝Spring注解开发_Servlet 3.0 与 SpringMVC 浅尝Spring注解开发,基于Spring 4.3.12 Servlet3.0新增了注解支持.异步处理,可以省去web.xml ...

  8. JAVAEE——SSH项目实战06:统计信息管理、Spring注解开发和EasyUI

    作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7190925.html 一.统计信息管理   二.Spring注解开发 1.service ...

  9. Spring注解开发-全面解析常用注解使用方法之生命周期

    本文github位置:https://github.com/WillVi/Spring-Annotation/ 往期文章:Spring注解开发-全面解析常用注解使用方法之组件注册 bean生命周期 ​ ...

随机推荐

  1. 基于FBX SDK的FBX模型解析与加载 -(四)

    8. 骨骼蒙皮动画 骨骼蒙皮动画是当前游戏引擎中最常用的一种动画方式,关于其基本原理网络上的资料较多,关于到涉及的其它较复杂操作,如插值.融合等在这里也就先不再讨论了,而且其实现方式也与具体引擎的动作 ...

  2. bzoj 1031: [JSOI2007]字符加密Cipher【后缀数组】

    算是SA的裸题了 把串复制一遍接在原串后面,然后求SA,然后按着SA的顺序输出尾字符即可 #include<iostream> #include<cstdio> #includ ...

  3. 黑客攻防技术宝典web实战篇:定制攻击自动化习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 指出使用自动技巧在应用程序中枚举标识符时用到的 3 个标识符“触点”. (a) HTTP ...

  4. Java关键字abstract与final总结

    关键字:abstract 用来修饰抽象类与抽象类中的方法 抽象类需要注意的几点: 抽象类不能被实例化.抽象类可以包含属性:方法:构造方法,但是构造方法不能用来new实例,只能被子类调用 有抽象方法的类 ...

  5. tarjan有向图的强连通

    强连通:在有向图G中,两个顶点间至少存在一条路径,则两个点强连通. 强连通图:在有向图中,每两个顶点都强连通,则有向图G就是一个强连通图. 强连通分量:在非强连通图中的极大强连通子图,就称为强连通分量 ...

  6. 转 Oracle中merge into的使用

    http://www.cnblogs.com/highriver/archive/2011/08/02/2125043.html

  7. (024)[工具软件]截屏录屏软件FSCapture(转)

    该软件比 Snipaste 增加的功能有滚动截图和屏幕录制. 原文地址:https://www.appcgn.com/faststone-capture.html FastStoneCapture,简 ...

  8. php Try Catch多层级异常测试

    <?php class a { public function a1 () { try { throw new Exception('123'); } catch (Exception $e) ...

  9. P1838 三子棋I

    题目描述 小a和uim喜欢互相切磋三子棋.三子棋大家都玩过是吗?就是在九宫格里面OOXX(别想歪了),谁连成3个就赢了. 由于小a比较愚蠢,uim总是让他先. 我们用9个数字表示棋盘位置: 123 4 ...

  10. Ubuntu rar的坑

    通过apt-get安装rar后,执行rar命令会有如下坑: rar: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (si ...