Aware接口
Aware接口中只是设置了对应的set方法,目前只定义了三个Aware
以BeanNameAware为例
package com.ez4sterben.spring.ioc.factory.aware;/*** bean名字清楚** @author ez4sterben* @date 2023/08/31*/
public interface BeanNameAware {/*** 设置beanName* @param beanName*/void setBeanName(String beanName);
}
检查Aware接口
/*** @param aware* @param clazz* @return boolean*/public boolean isImplAware(Class<?> aware, Class<?> clazz){Class<?>[] interfaces = clazz.getInterfaces();for (Class<?> anInterface : interfaces) {if (anInterface.equals(aware)) {return true;}}return false;}
通过invoke执行实现方法
/*** beanNameAware* @param bean* @throws Exception*/public void doBeanNameAware(Object bean) throws Exception {Class<?> aClass = bean.getClass();String beanName = parseBeanName(bean);Method setBeanName = aClass.getMethod("setBeanName", String.class);setBeanName.invoke(bean, beanName);}/*** 解析beanName* @param bean* @return {@link String}*/public String parseBeanName(Object bean){Class<?> aClass = bean.getClass();Component annotation = aClass.getAnnotation(Component.class);String value = annotation.value();if ("".equals(value)){String name = aClass.getSimpleName();String s = name.substring(0, 1).toLowerCase();value = s + name.substring(1);}return value;}/*** beanFactoryAware* @param beanFactory* @param bean* @throws NoSuchMethodException* @throws InvocationTargetException* @throws IllegalAccessException*/public void doBeanFactoryAware(BeanFactory beanFactory, Object bean) throws Exception {Class<?> aClass = bean.getClass();Method setBeanName = aClass.getMethod("setBeanFactory", BeanFactory.class);setBeanName.invoke(bean, beanFactory);}/*** applicationContextAware* @param beanFactory* @param bean* @throws Exception*/public void doApplicationContextAware(BeanFactory beanFactory, Object bean) throws Exception {Class<?> aClass = bean.getClass();Method setBeanName = aClass.getMethod("setApplicationContext", ApplicationContext.class);setBeanName.invoke(bean, new ApplicationContext(beanFactory));}
ApplicationContext是如何设计的
因为父类BeanFactory中的beanMap是私有的,为了保持一致,我们就要将对应的beanFactory对象传入构造方法然后给ApplicationContext中的beanMap赋值,由于java是值传递所以这两个对象中指向的beanMap是同一个
package com.ez4sterben.spring.ioc.context;import com.ez4sterben.spring.ioc.factory.support.BeanFactory;import java.util.Map;/*** 应用程序上下文** @author ez4sterben* @date 2023/08/30*/
public class ApplicationContext extends BeanFactory {private final Map<String, Object> beanMap;public ApplicationContext(BeanFactory beanFactory) {beanMap = beanFactory.getBeanMap();}@Overridepublic Map<String, Object> getBeanMap() {return beanMap;}
}
测试
为了方便测试,在BeanNameAware时向beanMap中put一下
主程序中的代码
if (beanScanner.isImplAware(BeanNameAware.class, clazz)) {beanFactory.doBeanNameAware(bean);}// BeanFactoryAwareif (beanScanner.isImplAware(BeanFactoryAware.class, clazz)) {beanFactory.doBeanFactoryAware(beanFactory, bean);}// ApplicationContextAwareif (beanScanner.isImplAware(ApplicationContextAware.class, clazz)) {beanFactory.doApplicationContextAware(beanFactory, bean);}
测试类中的代码
/*** 测试组件** @author ez4sterben* @date 2023/09/01*/
@Component
@Data
public class TestComponent implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {@Value("ez4sterben")private String name;private String age;@Overridepublic void setBeanName(String beanName) {System.out.println(beanName);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {System.out.println(applicationContext.getBeanMap().toString());}@Overridepublic void setBeanFactory(BeanFactory beanFactory) {System.out.println(beanFactory.getBeanMap().toString());}
}
测试结果