容器BeanFactory
public class BeanFactory {
private Map<String, Object> beanMap = new HashMap<>();
public void registerBean(String name, Object bean) {
beanMap.put(name, bean);
}
public Object getBean(String name) {
return beanMap.get(name);
}
}
BeanDefinition
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/de92e7283461de1204c570ef967d7c12.png)
@Data
@AllArgsConstructor
public class BeanDefinition {
private Class beanClass;
}
public interface BeanFactory {
Object getBean(String name) throws BeansException;
}
public class BeansException extends RuntimeException{
public BeansException(String msg, Exception e) {
super(msg, e);
}
}
public interface BeanDefinitionRegister {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
public interface SimpletonBeanRegister {
Object getSingleton(String beanName);
}
public class DefaultSingletonBeanRegister implements SimpletonBeanRegister{
private final Map<String, Object> singletonObjects = new HashMap<>();
@Override
public Object getSingleton(String beanName) {
return singletonObjects.get(beanName);
}
protected void addSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
}
}
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegister implements BeanFactory{
@Override
public Object getBean(String beanName) throws BeansException {
Object bean = getSingleton(beanName);
if (bean != null) {
return bean;
}
BeanDefinition beanDefinition = getBeanDefinition(beanName);
return createBean(beanName, beanDefinition);
}
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
protected abstract Object createBean(String name, BeanDefinition beanDefinition) throws BeansException;
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
return doCreateBean(beanName, beanDefinition);
}
protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
Class beanClass = beanDefinition.getBeanClass();
Object bean = null;
try {
bean = beanClass.newInstance();
} catch (Exception e) {
throw new BeansException("instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegister{
private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
@Override
protected BeanDefinition getBeanDefinition(String beanName) throws BeansException {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if(beanDefinition == null) {
throw new BeansException("no bean named '" + beanName + "' id defined", null);
}
return beanDefinition;
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
}
Bean实例化策略InstantiationStrategy
- 以前bean在AbstractAutowireCapableBeanFactory.doCreateBean方法中用beanClass.newInstance()来实例化,仅适用于bean有无参构造函数的时候。
- 抽象出实例化策略的接口InstantiationStrategy,两个实现类
- SimpleInstantiationStrategy,使用bean的构造函数来实例化。
- CglibSubclassingInstantiationStrategy,使用CGLIB动态生成子类。
public interface InstantiationStrategy {
Object instantiate(BeanDefinition beanDefinition) throws BeansException;
}
public class SimpleInstantiationStrategy implements InstantiationStrategy {
@Override
public Object instantiate(BeanDefinition beanDefinition) throws BeansException {
Class beanClass = beanDefinition.getBeanClass();
try {
Constructor constructor = beanClass.getDeclaredConstructor();
return constructor.newInstance();
} catch (Exception e) {
throw new BeansException("failed to instantiate [" + beanClass.getName() + "]", e);
}
}
}
public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy{
@Override
public Object instantiate(BeanDefinition beanDefinition) throws BeansException {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> proxy.invokeSuper(obj, args));
return enhancer.create();
}
}
bean填充属性
- BeanDefinition中增加属性对应的PropertyValues属性,为bean填充属性。
public class PropertyValue {
private final String name;
private final Object value;
public PropertyValue(String name, Object value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public Object getValue() {
return value;
}
}
public class PropertyValues {
private final List<PropertyValue> propertyValueList = new ArrayList<>();
public void addPropertyValue(PropertyValue pv) {
this.propertyValueList.add(pv);
}
public PropertyValue[] getPropertyValueList() {
return this.propertyValueList.toArray(new PropertyValue[0]);
}
public PropertyValue getPropertyValue(String propertyName) {
for (PropertyValue propertyValue : propertyValueList) {
if(propertyValue.getName().equals(propertyName)) {
return propertyValue;
}
}
return null;
}
}
- BeanDefinition新增PropertyValues属性。
@Data
@AllArgsConstructor
public class BeanDefinition {
public BeanDefinition(Class beanClass) {
this.beanClass = beanClass;
}
private Class beanClass;
private PropertyValues propertyValues;
}
- AbstractAutowireCapableBeanFactory在创建bean的时候,新增applyPropertyValues为bean填充属性。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
return doCreateBean(beanName, beanDefinition);
}
protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition);
applyPropertyValues(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
protected Object createBeanInstance(BeanDefinition beanDefinition) {
return getInstantiationStrategy().instantiate(beanDefinition);
}
protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) {
try {
PropertyValues propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues.getPropertyValueList()) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
BeanUtils.setFieldValue(bean, name, value);
}
} catch (Exception e) {
throw new BeansException("Error setting property values for bean: " + beanName, e);
}
}
}
- 新增BeanUtils工具类,使用反射设置bean的属性。
public class BeanUtils {
public static void setFieldValue(Object bean, String name, Object value) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = bean.getClass();
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(bean, value);
}
}
Confiuration后置处理器测试
ConfigurationClassPostProcessor
后置处理器,解析@Configration
注解。
public class TestBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Config.class);
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("config", beanDefinition);
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
Map<String, BeanFactoryPostProcessor> postProcessMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
postProcessMap.values().forEach(beanFactoryPostProcessor -> {
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
}
static class Bean1 {
@Autowired
private Bean2 bean2;
public Bean1() {
System.out.println("bean1 创建");
}
public Bean2 getBean2() {
return bean2;
}
}
static class Bean2 {
public Bean2() {
System.out.println("bean2 创建");
}
}
}
ClassPathXmlApplicationContext原理
public class TestApplicationContext {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions("spring.xml");
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
Bean1 bean1 = beanFactory.getBean(Bean1.class);
System.out.println(bean1.getBean2());
}
static class Bean1 {
private Bean2 bean2;
public Bean1() {
System.out.println("创建bean1.....");
}
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
public Bean2 getBean2() {
return bean2;
}
}
static class Bean2 {
public Bean2() {
System.out.println("创建bean2...");
}
}
}
AnnotationConfigServletWebServerApplicationContext
- 基于Web环境的sevlet容器。
- 该程序要运行在SpringBoot中,因为只有SpringBoot才内嵌了Tomcat容器。
- 运行该程序,在游览器访问
http://localhost:8080/hello
就可以收到回复。
public class TestWebServerApplication {
public static void main(String[] args) {
AnnotationConfigServletWebServerApplicationContext webServerApplicationContext =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
}
@Configuration
static class WebConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
@Bean("/hello")
public Controller controller() {
return new Controller() {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.getWriter().print("hello");
return null;
}
};
}
}
}
测试Bean生命周期
构造方法 -> 依赖注入 -> 初始化
。
@SpringBootApplication
public class SpringBootApplicationTest {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootApplicationTest.class, args);
MyBeanPostProcessor bean = applicationContext.getBean(MyBeanPostProcessor.class);
System.out.println(bean);
applicationContext.close();
}
}
- 演示bean的生命周期
@Component
public class LifeCycleBean {
public LifeCycleBean() {
System.out.println("构造方法");
}
@Autowired
public void getHome(@Value("${JAVA_HOME}") String home) {
System.out.println("依赖注入:home = " + home);
}
@PostConstruct
public void init() {
System.out.println("bean初始化");
}
@PreDestroy
public void destroy() {
System.out.println("销毁方法");
}
}
- 自定义后置处理器
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("执行构造方法之前...");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("执行构造方法之后...");
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("初始化之前...");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("初始化之后...");
}
return bean;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("依赖注入阶段 如@Autowird、@Value、@Resource...");
}
return pvs;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if ("lifeCycleBean".equals(beanName)) {
System.out.println("销毁方法之前...");
}
}
}
模板方法模式
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory myBeanFactory = new MyBeanFactory();
myBeanFactory.addPostProcessor(obj -> System.out.println("解析 @Autowired"));
myBeanFactory.addPostProcessor(obj -> System.out.println("解析 @Resource"));
myBeanFactory.getBean();
}
static class MyBeanFactory {
private final List<BeanPostProcessor> postProcessors = new ArrayList<>();
public void addPostProcessor(BeanPostProcessor beanPostProcessor) {
postProcessors.add(beanPostProcessor);
}
public Object getBean() {
Object o = new Object();
System.out.println("构造方法");
System.out.println("依赖注入");
for (BeanPostProcessor postProcessor : postProcessors) {
postProcessor.inject(o);
}
System.out.println("初始化");
return o;
}
}
static interface BeanPostProcessor {
void inject(Object obj);
}
}
Autowired后置处理器
public class TestBeanPostProcessor {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean(BeanTest1.class);
applicationContext.registerBean(BeanTest2.class);
applicationContext.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
applicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);
applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
ConfigurationPropertiesBindingPostProcessor.register(applicationContext.getDefaultListableBeanFactory());
applicationContext.refresh();
applicationContext.close();
}
}
class BeanTest1 {
private BeanTest2 beanTest2;
@Autowired
public void setBeanTest2(BeanTest2 beanTest2) {
System.out.println("@Autowired生效,beanTest2 = " + beanTest2);
this.beanTest2 = beanTest2;
}
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
System.out.println("@Value生效,home = " + home);
}
public BeanTest1() {
System.out.println("构造方法...");
}
@PostConstruct
public void init() {
System.out.println("@PostConstruct生效,初始化前...");
}
@PreDestroy
public void destroy() {
System.out.println("@PreDestroy生效,销毁...");
}
}
class BeanTest2 {}
Autowired注解解析过程
- Autowired注解的解析后置处理器:
AutowiredAnnotationBeanPostProcessor
。
public class TestAutowired {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("beanTest2", new BeanTest2());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
beanFactory.addEmbeddedValueResolver(new StandardEnvironment() :: resolvePlaceholders);
AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
autowiredAnnotationBeanPostProcessor.setBeanFactory(beanFactory);
BeanTest1 beanTest1 = new BeanTest1();
System.out.println(beanTest1);
Method findAutowiringMetadata = autowiredAnnotationBeanPostProcessor.getClass().getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(autowiredAnnotationBeanPostProcessor, "beanTest1", BeanTest1.class, null);
metadata.inject(beanTest1, "beanTest1", null);
System.out.println(beanTest1);
Field beanTest2 = BeanTest1.class.getDeclaredField("beanTest2");
DependencyDescriptor dd1 = new DependencyDescriptor(beanTest2, true);
Object o = beanFactory.resolveDependency(dd1, null);
System.out.println(o);
}
}
BeanFactory的后置处理器
- BeanFactory的后置处理器,主要对BeanFactory做一些增强。
public class TestBeanFactoryPostProcessor {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean(Config.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
applicationContext.registerBean(MapperScannerConfigurer.class, bd -> {
bd.getPropertyValues().add("basePackage", "mapper");
});
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
}
}
@Configuration
@ComponentScan("moudle")
public class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public DataSource dataSource() {
PooledDataSource pooledDataSource = new PooledDataSource();
pooledDataSource.setUrl("jdbc:mysql://localhost:3306/abc");
pooledDataSource.setUsername("root");
pooledDataSource.setPassword("abc");
return pooledDataSource;
}
}
自己解析ComponentScan注解
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
Optional<ComponentScan> optional = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (optional.isPresent()) {
ComponentScan componentScan = optional.get();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
for (String basePackage : componentScan.value()) {
String path = "classpath*:" + basePackage.replace(".", "/") + "/**/*.class";
Resource[] resources = resolver.getResources(path);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
if (beanFactory instanceof DefaultListableBeanFactory) {
DefaultListableBeanFactory beanFactory1 = (DefaultListableBeanFactory) beanFactory;
for (Resource resource : resources) {
MetadataReader metadataReader = factory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
System.out.println("类名:" + metadataReader.getClassMetadata().getClassName());
System.out.println("是否包含component注解:" + annotationMetadata.hasAnnotation(Component.class.getName()));
System.out.println("是否包含component的派生词注解:" + annotationMetadata.hasMetaAnnotation(Component.class.getName()));
if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
String beanName = generator.generateBeanName(beanDefinition, beanFactory1);
beanFactory1.registerBeanDefinition(beanName, beanDefinition);
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = factory.getMetadataReader(new ClassPathResource("Config.class"));
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
Set<MethodMetadata> methods = annotationMetadata.getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
System.out.println(method.getMethodName());
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
if (initMethod.length() > 0) {
builder.setInitMethodName(initMethod);
}
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
builder.setFactoryMethodOnBean(method.getMethodName(), "Config");
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
if (beanFactory instanceof DefaultListableBeanFactory) {
DefaultListableBeanFactory beanFactory1 = (DefaultListableBeanFactory) beanFactory;
beanFactory1.registerBeanDefinition(method.getMethodName(), beanDefinition);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class TestBeanFactoryPostProcessor {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean(Config.class);
applicationContext.registerBean(ComponentScanPostProcessor.class);
applicationContext.registerBean(AtBeanPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
}
}
解析Mapper注解
- Spring底层将Mapper接口加入到Spring容器中,使用的是如下配置。
@Configuration
@ComponentScan("moudle")
public class Config {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public DataSource dataSource() {
PooledDataSource pooledDataSource = new PooledDataSource();
pooledDataSource.setUrl("jdbc:mysql://localhost:3306/abc");
pooledDataSource.setUsername("root");
pooledDataSource.setPassword("abc");
return pooledDataSource;
}
@Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
}
- 自定义解析Mapper注解。
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:mapper/**/*.class");
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator annotationBeanNameGenerator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
MetadataReader metadataReader = factory.getMetadataReader(resource);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
if (classMetadata.isInterface()) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
AbstractBeanDefinition mapperBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName())
.getBeanDefinition();
String name = annotationBeanNameGenerator.generateBeanName(mapperBeanDefinition, registry);
registry.registerBeanDefinition(name, beanDefinition);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
- 加入后置处理器
public class TestBeanFactoryPostProcessor {
public static void main(String[] args) throws IOException {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean(Config.class);
applicationContext.registerBean(ComponentScanPostProcessor.class);
applicationContext.registerBean(AtBeanPostProcessor.class);
applicationContext.registerBean(MapperPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
}
}
Aware和InitializingBean
- Aware接口在初始化之前进行回调。InitializingBean初始化回调。
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {
@Override
public void setBeanName(String name) {
System.out.println("bean的名称:" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("容器对象: " + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化方法...");
}
}
public class TestAware {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("myBean", MyBean.class);
applicationContext.refresh();
applicationContext.close();
}
}
- Aware接口和@Autowired注入有什么区别,InitializingBean和@PostContustruct注解有什么区别?
- 后者使用注解需要额外有后置处理器进行处理才能生效。
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {
@Override
public void setBeanName(String name) {
System.out.println("bean的名称:" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("容器对象: " + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化方法...");
}
@Autowired
public void a(ApplicationContext applicationContext) {
System.out.println("Autowired 注入bean");
}
@PostConstruct
public void init() {
System.out.println("PostConstruct 进行初始化...");
}
}
public class TestAware {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("myBean", MyBean.class);
applicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);
applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
applicationContext.refresh();
applicationContext.close();
}
}
Autowired失效问题
- 在配置类中加入一个BeanFactoryPostProcessor后置处理器,会使@Autowired失效。
@Configuration
public class MyConfig1 {
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("Autowired 注入,applicationContext = " + applicationContext);
}
@PostConstruct
public void init() {
System.out.println("MyConfig1初始化...");
}
@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor() {
System.out.println("注入一个beanFactoryPostProcessor...");
return beanFactory -> {
System.out.println("运行beanFactoryPostProcessor...");
};
}
}
public class TestAware {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("MyConfig1", MyConfig1.class);
applicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);
applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
applicationContext.refresh();
applicationContext.close();
}
}
- 原始的javaBean初始化流程:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0ef6b0af42c4ca48136e32cac9c2eb36.png)
- 加入一个BeanFactoryPostProcessor后,就必须提前创建Java配置类,而此时BeanPostProcessor还未准备好,导致@Autowired等注解失效。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bb1d96db02c44334a9de69a2e8ad4377.png)
- 使用Aware接口和InitializingBean接口就可以避免这个问题。
@Configuration
public class MyConfig2 implements ApplicationContextAware, InitializingBean {
@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor() {
System.out.println("注入一个beanFactoryPostProcessor...");
return beanFactory -> {
System.out.println("运行myConfig2, beanFactoryPostProcessor...");
};
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化MyConfig2");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("aware applicationContext = " + applicationContext);
}
}
- 学到什么:
- Aware接口提供一种内置的注入手段,可以注入BeanFactory,ApplicationContext。
- InitializingBean接口提供一种内置的初始化手段。
- 内置的注入和初始化不受扩展功能的影响,总会被执行,因此Spring框架内部的类常用他们。
bean初始化和销毁
- bean的初始化有三种方法:@PostConstruct、实现InitializingBean接口、通过@Bean注解的initMethod指定。
- 测试这三种初始化的执行顺序:
public class BeanInit implements InitializingBean {
@PostConstruct
public void init1() {
System.out.println("PostConstruct 初始化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 接口初始化");
}
public void init2() {
System.out.println("@Bean注解注入指定初始化方法");
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2bb818ccac22fea0bda5d9abfa8e525a.png)
@PostConstruct
是CommonAnnotationBeanPostProcessor
进行解析,属于扩展功能,最先执行。InitializingBean
接口第二执行。@Bean
的initMethod属性在ConfigurationClassPostProcessor
解析BeanDefinetion时才会执行。- 销毁方法也有三种方式:@PreDestroy、实现DisposableBean接口、@Bean指定destroyMethod方法。
public class BeanDestroy implements DisposableBean {
@PreDestroy
public void destroy1() {
System.out.println("@PreDestroy进行销毁");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean接口销毁");
}
public void destroy2() {
System.out.println("@Bean执行的销毁");
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/36071ab98c3d14cce96fe88666eac139.png)
单例中注入多例bean问题
- 在一个单例中注入一个多例bean。
@Configuration
@ComponentScan("scope")
public class ScopeApplicationTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ScopeApplicationTest.class);
ScopeBean scopeBean = applicationContext.getBean(ScopeBean.class);
System.out.println(scopeBean);
System.out.println(scopeBean.getPropertyBean());
System.out.println(scopeBean.getPropertyBean());
System.out.println(scopeBean.getPropertyBean());
}
}
@Component
public class ScopeBean {
@Autowired
private PropertyBean propertyBean;
public PropertyBean getPropertyBean() {
return propertyBean;
}
}
@Scope("prototype")
@Component
public class PropertyBean {
}
- 预测输出多个实例,但是注入的多例,输出后还是单例。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/12e68172d8e859209be79ecb766ba6f0.png)
- 对于单例对象来讲,依赖注入只发生一次,后续创建的多例没有在使用到,因此始终使用的第一次依赖注入的对象。
- 解决方法一:加上
@Lazy
注解,生成多例的代理对象
。代理对象虽然是同一个,但是每次使用代理对象的任意方法时
,由代理对象生成一个新的对象。
@Component
public class ScopeBean {
@Lazy
@Autowired
private PropertyBean propertyBean;
public PropertyBean getPropertyBean() {
return propertyBean;
}
}
- 解决方法二:在@Scoper注解上添加代理配置
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Component
public class PropertyBean {
}
- 解决方法三:注入一个
ObjectFactory
工厂。
@Component
public class ScopeBean {
@Autowired
private ObjectFactory<PropertyBean> propertyBean;
public PropertyBean getPropertyBean() {
return propertyBean.getObject();
}
}
- 解决方法四:从applicationContext容器中获取。
@Component
public class ScopeBean {
@Autowired
private ApplicationContext applicationContext;
public PropertyBean getPropertyBean() {
return applicationContext.getBean(PropertyBean.class);
}
}
Spring容器启动流程
- 使用
AnnotationConfigApplicationContext
容器进行测试,类图如下。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d54952bd0e51817270c4168b792a3e97.png)