难度1-5
1.属性填充 难度1
方法调用完整路径
package: com.mashibing.selfeditor2.EditorTest.java
描述:案例一,spring通过子类继承PropertyEditorSupport调用setAsText解析Adress数据。将String数据转换成Address对象。
spring容器启动的时候需要注册PropertyEditorRegistrar的子类实现registerCustomEditors,注入相应的解析类和对应的实现类。
补充:此处的数据使用此标签解析.properties文件获取对象。
@PropertySource(“classpath:customer.properties”)
@Value(“
c
u
s
t
o
m
e
r
.
n
a
m
e
"
)
@
V
a
l
u
e
(
"
{customer.name}") @Value("
customer.name")@Value("{customer.address}”)
public class AddressPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
String[] s = text.split("_");
Address address = new Address();
address.setProvince(s[0]);
address.setCity(s[1]);
address.setTown(s[2]);
this.setValue(address);
}
}
public class AddressPropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Address.class, new AddressPropertyEditor());
}
}
2.代理实现 难度2
cglib
程序运行时ASM修改class字节码文件,需要创建Enhancer对象调用create完成对象调用。(启动时不生成文件)
1.实现MethodInterceptor接口,重写intercept()
2.使用Enhancer对象.create()产生代理对象
jdk
扩展部分:
程序编译的时候生成代理class文件,使用InvocationHandler的回调方法invoke执行具体方法。
使用Proxy.newProxyInstance(loader, interfaces, h);创建具体类对象。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理
2、如果目标对象实现了接口,也可以强制使用CGLIB
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
JDK和CGLIB动态代理的区别
https://blog.csdn.net/weixin_45723046/article/details/124422910
3.tx 难度5
https://blog.csdn.net/yangxiaofei_java/article/details/113634986
事物传播机制
https://blog.csdn.net/szy350/article/details/122466050
4.AOP 难度5
https://blog.csdn.net/yangxiaofei_java/article/details/113634986
5.IOC 难度5
循环依赖
https://blog.csdn.net/a745233700/article/details/110914620
6.常用注解 难度3
此类被用来扫描注解,比如@Component,@Repository,@Service,@Controller,在创建对象的时候做一些基本的配置工作
ClassPathBeanDefinitionScanner
7.对象实例after postProcessor 难度1,同1#
测试案例path:
com.mashibing.resolveBeforeInstantiation.Test.java
com.mashibing.populateBean.TestPopulate.java
可以用来做什么,条件判断,日志记录?属性填充
path全路径:
AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {}
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { }
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {}
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {}
// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
// //postProcessAfterInstantiation:一般用于设置属性
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {}
// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
//postProcessProperties:在工厂将给定的属性值应用到给定Bean之前,对它们进行后处理,不需要任何属性扫描符。该回调方法在未来的版本会被删掉。
// -- 取而代之的是 postProcessPropertyValues 回调方法。
// 让ibp对pvs增加对bw的Bean对象的propertyValue,或编辑pvs的proertyValue
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {}
// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {}
//postProcessPropertyValues:一般进行检查是否所有依赖项都满足,例如基于"Require"注释在 bean属性 setter,
// -- 替换要应用的属性值,通常是通过基于原始的PropertyValues创建一个新的MutablePropertyValue实例, 添加或删除特定的值
// -- 返回的PropertyValues 将应用于bw包装的bean实例 的实际属性值(添加PropertyValues实例到pvs 或者 设置为null以跳过属性填充)
//回到ipd的postProcessPropertyValues方法
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
子类实现InstantiationAwareBeanPostProcessor,重写
1.在bean实例化之前调用
postProcessBeforeInstantiation
2.在bean实例化之后调用
postProcessAfterInstantiation
3.当使用注解的时候,通过这个方法来完成属性的注入
postProcessProperties
4.属性注入后执行的方法,在5.1版本被废弃
postProcessPropertyValues
8.Bean定义注入 难度1
BeanDefinitionRegistryPostProcessor.java
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
BeanFactoryPostProcessor.java
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
注入PropertyValues,修改value
- selfAutowired 注入板块忘记了。
9.Bean定义注入 难度1 案例不全,没有记录正确的过程
@FunctionalInterface
public interface Converter<S, T> {
/**
* 将S类型转换成T类型
*
* Convert the source object of type {@code S} to target type {@code T}.
* @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
* @return the converted object, which must be an instance of {@code T} (potentially {@code null})
* @throws IllegalArgumentException if the source cannot be converted to the desired target type
*/
@Nullable
T convert(S source);
}
<bean id="studentConverter" class="com.mashibing.selfConverter.StudentConverter"></bean>
<bean id ="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="studentConverter"></ref>
</set>
</property>
</bean>
10 AnnotationUtils
11 AnnotatedElementUtils
12 DI注入的七种方式
- 使用xml的方式来声明Bean的定义Spring容器在启动的时候会加载并解析这个xml,把bean装在到IOC容器中
- 使用@ComponentScan注解来扫描声明了@Controller,@Service,@Repository,@Component注解的类
- 使用@Confinguration注解声明配置类,并使用@Bean注解实现Bean的定义,这种方式其实是xml配置方式的一种演变,是Spring迈入到无配置化时代的里程碑
- 使用@Import注解,导入配置类或者普通的Bean
- 使用FactoryBean工厂bean,动态构建一个Bean实例,Spring Could OpenFeign里面的动态代理实例就是使用FactoryBean来实现的。
- 实现ImportBeanDefinitionResgister接口,可以动态注入Bean实例。这个在Spring Boot里面的启动注解用到
- 实现ImportSelector接口,动态批量注入配置类或者Bean对象,这个在SpringBoot里面的自动装配机制里面有用到
https://www.bilibili.com/video/BV1BP4y127jA/?spm_id_from=333.337.search-card.all.click
spring boot,补充
https://blog.csdn.net/woshilijiuyi/article/details/84147483
https://blog.csdn.net/woshilijiuyi/article/details/83934407
spring could,补充
https://blog.csdn.net/duqingqing5666/article/details/119395052?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166793922816800184153631%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166793922816800184153631&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-119395052-null-null.142v63control,201v3add_ask,213v2t3_esquery_v2&utm_term=springcould%E6%BA%90%E7%A0%81&spm=1018.2226.3001.4187
https://blog.csdn.net/qq_34684394/article/details/120103677?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166793922816800184153631%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166793922816800184153631&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-120103677-null-null.142v63control,201v3add_ask,213v2t3_esquery_v2&utm_term=springcould%E6%BA%90%E7%A0%81&spm=1018.2226.3001.4187