重新学习Spring注解——ICO
02、组件注册-@Configuration&@Bean给容器中注册组件
03、组件注册-@ComponentScan-自动扫描组件&指定扫描规则
04、组件注册-自定义TypeFilter指定过滤规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | @Configuration //告诉Spring这是一个配置类 @ComponentScans ( value = { @ComponentScan (value = "com.learn" , includeFilters = { /* @Filter(type=FilterType.ANNOTATION,classes={Controller.class}), @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/ @Filter (type = FilterType.CUSTOM, classes = {MyTypeFilter. class }) }, useDefaultFilters = false ) } ) //@ComponentScan value:指定要扫描的包 //excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件 //includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件 //FilterType.ANNOTATION:按照注解 //FilterType.ASSIGNABLE_TYPE:按照给定的类型; //FilterType.ASPECTJ:使用ASPECTJ表达式 //FilterType.REGEX:使用正则指定 //FilterType.CUSTOM:使用自定义规则 public class MainConfig { //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id @Bean ( "person" ) public Person person01() { return new Person( "lisi" , 20 ); } } |
05、组件注册-@Scope-设置组件作用域
06、组件注册-@Lazy-bean懒加载
07、组件注册-@Conditional-按照条件注册bean
08、组件注册-@Import-给容器中快速导入一个组件
给容器中注入注解组件:
1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)
2)、@Bean[导入的第三方包里面的组件]
3)、@Import [快速给容器中导入一个组件]
09、组件注册-@Import-使用ImportSelector
10、组件注册-@Import-使用ImportBeanDefinitionRegistrar
11、组件注册-使用FactoryBean注册组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | @Conditional ({WindowsCondition. class }) @Configuration @Import ({Color. class , Red. class , MyImportSelector. class , MyImportBeanDefinitionRegistrar. class }) //@Import导入组件,id默认是组件的全类名 public class MainConfig2 { //默认是单实例的 /** * ConfigurableBeanFactory#SCOPE_PROTOTYPE * * @return\ * @Scope:调整作用域 prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。 * 每次获取的时候才会调用方法创建对象; * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。 * 以后每次获取就是直接从容器(map.get())中拿, * request:同一次请求创建一个实例 * session:同一个session创建一个实例 * <p> * 懒加载: * 单实例bean:默认在容器启动的时候创建对象; * 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化; * @see ConfigurableBeanFactory#SCOPE_SINGLETON * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion */ // @Scope("prototype") @Lazy @Bean ( "person" ) public Person person() { System.out.println( "给容器中添加Person...." ); return new Person( "张三" , 25 ); } /** * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean * <p> * 如果系统是windows,给容器中注册("bill") * 如果是linux系统,给容器中注册("linus") */ @Bean ( "bill" ) public Person person01() { return new Person( "Bill Gates" , 62 ); } @Conditional (LinuxCondition. class ) @Bean ( "linus" ) public Person person02() { return new Person( "linus" , 48 ); } /** * 给容器中注册组件; * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类] * 2)、@Bean[导入的第三方包里面的组件] * 3)、@Import[快速给容器中导入一个组件] * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名 * 2)、ImportSelector:返回需要导入的组件的全类名数组; * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中 * 4)、使用Spring提供的 FactoryBean(工厂Bean); * 1)、默认获取到的是工厂bean调用getObject创建的对象 * 2)、要获取工厂Bean本身,我们需要给id前面加一个& * &colorFactoryBean */ @Bean public ColorFactoryBean colorFactoryBean() { return new ColorFactoryBean(); } } |
12、生命周期-@Bean指定初始化和销毁方法
13、生命周期-InitializingBean和DisposableBean
14、生命周期-@PostConstruct&@PreDestroy
15、生命周期-BeanPostProcessor-后置处理器
16、生命周期-BeanPostProcessor原理
17、生命周期-BeanPostProcessor在Spring底层的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /** * bean的生命周期: * bean创建---初始化----销毁的过程 * 容器管理bean的生命周期; * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法 * * 构造(对象创建) * 单实例:在容器启动的时候创建对象 * 多实例:在每次获取的时候创建对象\ * * BeanPostProcessor.postProcessBeforeInitialization * 初始化: * 对象创建完成,并赋值好,调用初始化方法。。。 * BeanPostProcessor.postProcessAfterInitialization * 销毁: * 单实例:容器关闭的时候 * 多实例:容器不会管理这个bean;容器不会调用销毁方法; * * * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization, * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization * * BeanPostProcessor原理 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值 * initializeBean * { * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); *} * * * * 1)、指定初始化和销毁方法; * 通过@Bean指定init-method和destroy-method; * 2)、通过让Bean实现InitializingBean(定义初始化逻辑), * DisposableBean(定义销毁逻辑); * 3)、可以使用JSR250; * @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法 * @PreDestroy:在容器销毁bean之前通知我们进行清理工作 * 4)、BeanPostProcessor【interface】:bean的后置处理器; * 在bean初始化前后进行一些处理工作; * postProcessBeforeInitialization:在初始化之前工作 * postProcessAfterInitialization:在初始化之后工作 * * Spring底层对 BeanPostProcessor 的使用; * bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor; * * */ @ComponentScan ( "com.learn.bean" ) @Configuration public class MainConfigOfLifeCycle { //@Scope("prototype") @Bean (initMethod= "init" ,destroyMethod= "detory" ) public Car car(){ return new Car(); } } |
18、属性赋值-@Value赋值
19、属性赋值-@PropertySource加载外部配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /** * Profile: * Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能; * * 开发环境、测试环境、生产环境; * 数据源:(/A)(/B)(/C); * * * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件 * * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境 * 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效 * 3)、没有标注环境标识的bean在,任何环境下都是加载的; */ @PropertySource (value={ "classpath:/dbconfig.properties" }) @Configuration public class MainConfigOfProfile implements EmbeddedValueResolverAware{ @Value ( "${db.user}" ) private String user; private StringValueResolver valueResolver; private String driverClass; @Profile ( "test" ) @Bean public Yellow yellow(){ return new Yellow(); } @Profile ( "test" ) @Bean ( "testDataSource" ) public DataSource dataSourceTest( @Value ( "${db.password}" )String pwd) throws Exception{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl( "jdbc:mysql://localhost:3306/test" ); dataSource.setDriverClass(driverClass); return dataSource; } @Profile ( "dev" ) @Bean ( "devDataSource" ) public DataSource dataSourceDev( @Value ( "${db.password}" )String pwd) throws Exception{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl( "jdbc:mysql://localhost:3306/ssm_crud" ); dataSource.setDriverClass(driverClass); return dataSource; } @Profile ( "prod" ) @Bean ( "prodDataSource" ) public DataSource dataSourceProd( @Value ( "${db.password}" )String pwd) throws Exception{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl( "jdbc:mysql://localhost:3306/scw_0515" ); dataSource.setDriverClass(driverClass); return dataSource; } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this .valueResolver = resolver; driverClass = valueResolver.resolveStringValue( "${db.driverClass}" ); } } |
20、自动装配-@Autowired&@Qualifier&@Primary
21、自动装配-@Resource&@Inject
22、自动装配-方法、构造器位置的自动装配
23、自动装配-Aware注入Spring底层组件&原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /** * 自动装配; * Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值; * * 1)、@Autowired:自动注入: * 1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值 * 2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找 * applicationContext.getBean("bookDao") * 3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名 * 4)、自动装配默认一定要将属性赋值好,没有就会报错; * 可以使用@Autowired(required=false); * 5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean; * 也可以继续使用@Qualifier指定需要装配的bean的名字 * BookService{ * @Autowired * BookDao bookDao; * } * * 2)、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解] * @Resource: * 可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的; * 没有能支持@Primary功能没有支持@Autowired(reqiured=false); * @Inject: * 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能; * @Autowired:Spring定义的; @Resource、@Inject都是java规范 * * AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能; * * 3)、 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值 * 1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配 * 2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取 * 3)、放在参数位置: * * 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx); * 自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware; * 把Spring底层一些组件注入到自定义的Bean中; * xxxAware:功能使用xxxProcessor; * ApplicationContextAware==》ApplicationContextAwareProcessor; * * * */ @Configuration @ComponentScan ({ "com.learn.service" , "com.learn.dao" , "com.learn.controller" , "com.learn.bean" }) public class MainConifgOfAutowired { @Primary @Bean ( "bookDao2" ) public BookDao bookDao(){ BookDao bookDao = new BookDao(); bookDao.setLable( "2" ); return bookDao; } /** * @Bean标注的方法创建对象的时候,方法参数的值从容器中获取 * @param car * @return */ @Bean public Color color(Car car){ Color color = new Color(); color.setCar(car); return color; } } |
24、自动装配-@Profile环境搭建.avi
25、自动装配-@Profile根据环境注册bean
(1)使用命令行动态参数:见第19配置好不同数据源,在虚拟机位置添加:-Dspring.profiles.active=test
(2) 代码的方式激活某种环境
@Test public void test01(){ /* * AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class); * 源码: * public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { * this(); * register(annotatedClasses); * refresh(); * } * 改造成无参构造: * register(annotatedClasses)与refresh()仍然需要执行 * */ // 1、创建一个AnnotationConfigApplicationContext AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 2、设置激活的环境 ;源码(可以同时激活多种环境):public void setActiveProfiles(String... profiles) context.getEnvironment().setActiveProfiles("dev"); // 3、设置主配置类 context.register(MainConfigOfAutowired.class); // 4、刷新容器 context.refresh(); }
26、IOC-小结
posted on 2019-08-26 23:44 betterLearing 阅读(391) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何调试 malloc 的底层源码
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 因为Apifox不支持离线,我果断选择了Apipost!
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端