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();
}
@Override
public Map<String, Object> getBeanMap() {
return beanMap;
}
}
测试
为了方便测试,在BeanNameAware时向beanMap中put一下
主程序中的代码
if (beanScanner.isImplAware(BeanNameAware.class, clazz)) {
beanFactory.doBeanNameAware(bean);
}
// BeanFactoryAware
if (beanScanner.isImplAware(BeanFactoryAware.class, clazz)) {
beanFactory.doBeanFactoryAware(beanFactory, bean);
}
// ApplicationContextAware
if (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;
@Override
public void setBeanName(String beanName) {
System.out.println(beanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println(applicationContext.getBeanMap().toString());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println(beanFactory.getBeanMap().toString());
}
}
测试结果