配置beans.xml 给一个id方便从容器中获取 可以通过property作为一个属性的赋值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgFFaJDX-1590551049657)((https://cdn.jsdelivr.net/gh/1392517138/imgRepository@master/image-20200511220207948.png)] 这是以前的一个配置文件 开始使用,写一个测试类 以前配置文件的方式被替换为了配置类 2.回到MainTest,通过AnnotationConfigApplicationContext注解式的config,它传入的就是这个配置类。相当于是穿配置类的位置。 在实际开发中,包的扫描写得比较多 3. 写在配置类中 4. 效果演示 发现其中mainConfig也是一个组件,是因为@Configuration也是一个@Component 5. excludeFilters,过滤不扫描的内容。 它是一个Filter()数组 6.@ComponentScan 在8几以上中才可以 如果不是,就使用@ComponentScan,指定扫描策略 FilterType.ASSIGNABLE_TYPE 按照给定的类型 FilterType.ASPECTJ 使用ASPECTJ表达式(不太常用) FilterType.REGEX 使用正则表达式 实现TypeFilter top.p3wj中的每一个类都会进入进行匹配 默认单实例 改为多实例后 这其实就相当于在xml文件中,Bean里加上scope ioc容器启动会创建对象,放到ioc容器中,以后每次获取就是直接从容器(map.get())中拿 1.下面演示单实例 把test02中下面的注释掉 2.多实例情况 就不打印“给容器中添加Person…”了 ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象。 即在第一次获得的时候才加载 若取消懒加载 先前准备: 要求: 通过applicationContext拿到一个运行的环境 要传入一个Condition数组。@Conditional({}) 配置两个实现了Condition的类 设置一下参数 可以做非常多的判断条件 也可放在类上,含义即满足当前条件,这个类中配置的 所有bean注册才能生效 注意: 若有多个,则为按照顺序判断(猜测)已经设置-Dos.name=Linux 1.新建一个color类 2.使用@Import 3.测试 可以导入多个,现写一个Red类 前提条件: 打上断点进行调试 结果: 如果返回null:—->return null;会报空指针,因为在拿类名的时候 所以不要返回null,可以返回一个空数组 可获取到所以注解信息及类相关的 因为是return的,所以也被导入了 command+alt+b查看实现类 注意,import方式注入的名称为全类名 通过此方法把对象放到容器中 结果: isSingleton是false情况下是多实例,每一次获取都调用getObject Reason: 在以前,可以指定初始化和销毁方法 创建Car 以上针对单实例对象 通过调用close()关闭 2.当改为多实例Bean当时候 2.1 当获取的时候才会初始化 2.2 容器关闭后不会进行销毁 在这里提出一个问题,@Bean不搭配@Configuration使用跟搭配有什么区别(还未解决) 通过包扫描的方式进行注册,同时通过实现接口进行初始化和销毁 这是java规范的注解,目前java8能用 先创建对象-》〉》〉初始化 打断点debug一下 1.查看调用方法栈,往上依次看 10.来看怎么创建的 12.创建好后准备初始化 13.原理体现的地方 点进去看一下,里面的内容 我们来看一下ApplicationContextAwareProcessor,实现的BeanPostProcessor 其实看看之前写的MyBeanPostProcessor,也是实现了它的方法 ApplicationContextAwareProcessor是封装好了这些实现 再来看下ApplicationContextAware 如果是就调用下面的 invokeAwareInterfaces(bean); 点进去查看 来debug看一下 准备如下: Debug: 并且会把ioc容器传进来,怎么传进来呢?接下来根据方法栈来看下之前调用的 1.在这里调用 postProcessBeforeInitialization 再来看看 BeanValidationPostProcessor 该PostProcessor是用来做数据校验的,在web用的比较多 再来看看 InitDestroyAnnotationBeanPostProcessor 为什么Dog中标注了这样的注解它就知道在哪执行呢? 我们打一个断点来看一下 **出了个问题,init不执行(以后解决)**发现的问题为: 这里重写了: 再来看看 AutowiredAnnotationBeanPostProcessor @Autowired也是通过这个来注值的 并没有赋值,在以前的beans.xml文件中: 是通过这样的方式 我们有一个对应的@Value 如果要在beans.xml中使用${}取properties中的值就要配上这个名称空间 并采用以下方式: 但是启动会报错: 这是因为少了context相关的解析文件。 解决如下,在 xsi:schemaLocation 中添加: 因为是运行时候的变量,所以还可以用applicationContext.getEnvironment 也可用PropertySources,是一个可重复标注的注解 此外注意,在此版本中: 准备: 两个Dao,通过labe的设置看注入的是哪一个。相同类型,一个叫bookDao,一个叫bookDao2 你可以看见第二个报错了,因为按照BookDao.class去找的 @Autowired 如果找到相同类型组件,就需要按照属性名去寻找 如:BookDao bookDao;就是按照bookDao去寻找 我现在按照名字去找,可以发现这两个BookDao是不一样的,即@Repository与@Bean返回 注入的两者不一样 虽然在BookService通过@Autowired默认方法吗作为id注入,但是我们可以通过@Qualifier去改变 另外: 将BookDao的@Repository注释掉 此时相当于容器中没有任何一个BookDao 运行时会报错 看一下@Autowired,我们要达到没有该Bean就不注入的效果 此时service就正常了 我们发现如果容器同一个类型要用多个就要写多次@Qualifier,那么可以选用@Primary,即让spring进行自动装配的时候,默认使用首选的bean 总结 @Resource是默认按照属性的名称 @Inject需要导入maven依赖 @Autowired: 1、标注在方法位置 给Car也加上@Component,通过配置类@ComponentScan扫描进去 默认加载ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作 加到参数上,效果也一样 如果只有一个有参构造器,@Autowired可以不用写 以@Bean的方式注入 准备 自定义 传进来这个applicationContext我们就能用,类似这样的有很多 总接口是Aware 找几个Aware来看一下 解析字符串的值 这些Aware都是由相应的XXXAwareProcessor来处理的 我们来看一下怎么将applicationContext注入进来的 打一个断点: 跟之前是类似的 总结一下 引入c3p0和mysql-connector 配置dbconfig.properties 并加载@PropertySource(“classpath:/dbconfig.properties”) 来自spring的黑科技 另一种方式,Aware接口 那么来看看@Profile 默认是”default”,可以看见只有标了”default”才会被加入到容器中 那么怎么切换环境呢? 最简单的方法,使用命令行参数 2.代码的方式 配置类一注册进来,容器就启动刷新了,环境还没有设置好 如果写在类上,就代表整个类里面的内容是否会被加载
01 spring 常用注解 原理 逻辑 代码演示
文章目录
一、组件注册
1.1-spring注解驱动开发
1.2-组件注册 @Configuration
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.12.RELEASE</version> </dependency>
1.3-组件注册 Configuration、Bean、ComponentScan(s)、TypeFilter
3. 通过getBeanDefinitionNames可获得Bean容器中组件的所有名称
<!--包扫描、只要标注了@Controller、@Service、@Repository、@Component,都会被自动扫描加入容器中--> <context:component-scan base-package="top.p3wj"></context:component-scan>
//excludeFilters = Filter[] 指定扫描的时候按照规则排除哪些规则 //includeFilters = Filter[] 指定扫描的时候只需要包含哪些组件 //useDefaultFilters 默认为true,加载所有组件
1.4-组件注册 @Scope
* ConfigurableBeanFactory#SCOPE_PROTOTYPE prototype 多实例 * ConfigurableBeanFactory#SCOPE_SINGLETON singleton 单实例(默认值) * org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request 同一次请求创建一个实例 * org.springframework.web.context.WebApplicationContext#SCOPE_SESSION session 同一个session创建一个实例
1.5-组件注册@Lazy-bean懒加载
1.6-组件注册 @Conditional 按照条件给容器注入Bean
@Conditional ,按照一定的条件进行判断,满足条件给容器中注册Bean
* 如果是MacOs,给容器注册 jobs * 如果是linux,给容器注册linus
//boolean pserson = registry.containsBeanDefinition("pserson");//也可判断容器中是否包含一个Bean。也可给容器中注册Bean
1.7-组件注册 @Import快速导入
/** * 给容器中注册组件: * 1) 包扫描+组件标注注解 (@Controller/@Service/@Repository/@Component)[自己写的] * 2) @Bean[导入的第三方包里面的组件],但是它比较麻烦(需要return等) * 3) @Import[快速给容器导入一个组件] */
//导入组件,id默认是组件的全类名,@Import(要导入到容器中到组件),容器中就会自动注册这个组件,id默认是全类名
1.7.1-组件注册 @ImportSelector
2) ImportSelector:返回需要导入的组件的全数组
public interface ImportSelector { /** * Select and return the names of which class(es) should be imported based on * the {@link AnnotationMetadata} of the importing @{@link Configuration} class. */ String[] selectImports(AnnotationMetadata importingClassMetadata); }
return new String[]{};
1.7.2-组件注册 @ImportBeanDefinationRegister
ImportBeanDefinitionRegistrar 手动注册Bean
1.8-组件注册 @FactoryBean
//工厂获取的是调用getObject创建的对象
@Override public boolean isSingleton() { return false; }
使用Spring提供的FactoryBean(工厂Bean) * 1) 默认获取到到是工厂bean调用getObject创建的对象 * 2) 要获取工厂Bean本身,我们需要给id前面加一个& * &colorFactoryBean
二、生命周期
2.1-生命周期 @Bean指定初始化和销毁方法
public class MainConfigOfLifeCycle { @Bean public Car car(){ return new Car(); } }
* bean的生命周期: * bean创建---初始化---销毁的过程 * 容器管理bean的生命周期: * 我们可以自定义初始化和销毁方法;容器在 bean进行到当前生命周期的时候调用我们自定义的初始化和销毁方式 *构造(对象创建) * 单实例:在容器启动的时候创建对象 * 多实例:在每次获取的时候创建对象 *初始化: * 对象创建完成,并赋值好,调用初始化方法。。。 *销毁: * 单实例:容器关闭的时候 * 多实例:容器不会管理这个bean,容器不会调用销毁方法;需要手动调用 * 1)、指定初始化和销毁方法: * 指定init-method和destroy-method方法
2.2-生命周期 InitializingBean和DisposableBean
2)、通过让Bean实现InitializingBean(定义初始化逻辑)
2.3-生命周期 @PostConstruct和@PreDestroy
* 3)、可以使用JSR250: * @PostConstruct:在bean创建完成并且属性赋值完成:来执行初始化方法 * @PreDestroy:在容器销毁bean之前通知我们进行清理工作
2.4-生命周期 BeanPostProcessor(后置处理器)
* 4)、BeanPostProcessor【interface】,bean的后置处理器: * 在bean初始化前后进行一些处理工作: * postProcessBeforeInitialization:在初始化之前工作 * postProcessAfterInitialization:在初始化之后工作
2.4.1-生命周期 BeanPostProcessor原理
applyBeanPostProcessorsAfterInitialization 就不看了,类似的
* 遍历得到容器中所有的BeanPostProcessor:挨个执行beforeInitialization * 一单返回null,跳出for循环,不会执行后面单BeanPostProcessor * populateBean(beanName, mbd, instanceWrapper); 给bean进行属性赋值的 * * initializeBean: * { * wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); * this.invokeInitMethods(beanName, wrappedBean, mbd); * wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); * }
2.4.2-生命周期 spring底层对BeanPostProcessor的使用
我还重写了个BeanPostProcessor的postProcessBeforeInitialization方法,@PostConstruct也是用* spring底层对BeanPostProcessor的使用 * bean赋值、注入其他组件,@Autowired,生命周期注解功能,@Async,等等 * 都是用BeanPostProcessor来完成的
三、属性赋值
3.1-属性赋值 @Value
ApplicationContext applicationContext2 = new ClassPathXmlApplicationContext("beans.xml");
3.2-属性赋值 @PropertySource加载外部配置文件
@PropertySource() 属性的来源
四、自动装配
4.1-自动装配 @Autowired & @Qualifier & @Primary
4.2-自动装配 JSR250-@Resource、JSR330-@Inject
4.3-自动装配 方法、构造器位置的自动装配 & Aware注入Spring底层组件 & 原理
4.4-自动装配 @Profile 根据环境注册Bean
* @description Profile: * Spring为我们提供的可以根据当前环境,动态地激活和切换一些列组件的功能: * 开发环境、测试环境、生产环境: * 数据源:(/A)(/B)(/C) * @Profile 指定组件在哪个环境下才能被注册到容器中。不指定任何环境下都能注册这个组件
* 1)、加了环境表示的bean,只有这个环境被激活的时候才能被注册到容器中,默认是default环境
针对于AnnotationConfigApplicationContext
* @Profile 指定组件在哪个环境下才能被注册到容器中。不指定任何环境下都能注册这个组件 * 1)、加了环境表示的bean,只有这个环境被激活的时候才能被注册到容器中,默认是default环境 * 2) 、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效 * 3)、没有标注环境标识的bean,任何环境下都会加载
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算