自己动手写一个spring之IOC_4

写在前面

本文继续完善IOC部分内容,主要是增加beanfactory相关内容,使其变得更加丰满,以及增加事件通知相关内容,从而能够更好的感知程序执行的进程,以及时做出需要执行的动作。
源码

1:增强beanfactory

在Java程序语言中,我们用一个interface代表一种特性(如java.io.Closeable代表需要关闭释放资源)或者是一种能力(如java.lang.Cloneable代表具备克隆的能力),这样特性以及能力互相独立,某个类想要拥有某个特性或者是某个能力的话,只需要实现对应的接口就行了。这种设计原则,还有一个专门的名称interface segregation,即接口隔离原则。我们就来按照接口隔离原则来强化beanfactory。

1.1:具备信息列举能力的beanfactory

/**
 * 拥有列举能力的bean工厂,比如列举所有的bean名称,某种类型的bean列表等
 */
public interface ListableBeanFactory extends BeanFactory {

	boolean containsBeanDefinition(String beanName);

	int getBeanDefinitionCount();

	String[] getBeanDefinitionNames();

	String[] getBeanNamesForType(Class<?> type);

	<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

}

比如需要获取某个类型的bean名称列表就可以使用该接口了。

1.2:具有可配置能力的beanfactory

/**
 * 支持配置的bean工厂,比如配置bean处理器等
 */
public interface ConfigurableBeanFactory extends
        BeanFactory, SingletonBeanRegistry {
    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";

    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

    int getBeanPostProcessorCount();

    void registerDependentBean(String beanName, String dependentBeanName);

    String[] getDependentBeans(String beanName);

    String[] getDependenciesForBean(String beanName);
}

比如需要配置后置bean处理器,就可以使用该接口。

1.3:具备信息列举能力的和可配置能力的beanfactory

单点麻烦,那就直接来个煎饼果子套餐:

/**
 * 可列举,可配置的套餐接口
 */
public interface ConfigurableListableBeanFactory
        extends ListableBeanFactory, AutowireCapableBeanFactory,
        ConfigurableBeanFactory {
}

1.4:优化AutowireCapableBeanFactory

在前面的内容中,AutowireCapableBeanFactory是一个具体的实现类,它提供了解析@Autowired注解注入bean的能力,这里也按照当前的套路进行优化,删除原有的AutowireCapableBeanFactory类,然后定义AutowireCapableBeanFactory接口:

/**
 * 拥有@Autowired注解处理能力的bean工厂
 */
public interface AutowireCapableBeanFactory extends BeanFactory {
    int AUTOWIRE_NO = 0;
    int AUTOWIRE_BY_NAME = 1;
    int AUTOWIRE_BY_TYPE = 2;

    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;
}

定义抽象类,给出默认的实现:

public abstract class AbstractAutowireCapableBeanFactory
        extends AbstractBeanFactory implements
        AutowireCapableBeanFactory {
}

定义实现类:

public class DefaultListableBeanFactory extends
        AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory {
}

DefaultListableBeanFactory就是spring实际使用的bean工厂类了,可以看作是IOC的发动机。是核心类。uml图:
在这里插入图片描述

2:环境支持

定义可以获取系统属性的接口:

public interface PropertyResolver {
    boolean containsProperty(String key);
    String getProperty(String key);
    String getProperty(String key, String defaultValue);
    <T> T getProperty(String key, Class<T> targetType);
    <T> T getProperty(String key, Class<T> targetType, T defaultValue);
    <T> Class<T> getPropertyAsClass(String key, Class<T> targetType);
    String getRequiredProperty(String key) throws IllegalStateException;
    <T> T getRequiredProperty(String key, Class<T> targetType) throws 
IllegalStateException;
    String resolvePlaceholders(String text);
    String resolveRequiredPlaceholders(String text) throws 
IllegalArgumentException;
}

按照接口隔离原则,定义环境获取能力的接口:

public interface EnvironmentCapable {
    Environment getEnvironment();
}

定义总的环境接口:

public interface Environment extends PropertyResolver {
    String[] getActiveProfiles();
    String[] getDefaultProfiles();
    boolean acceptsProfiles(String... profiles);
}

3:事件

3.1:事件对象

/**
 * 定义应用事件
 */
public class ApplicationEvent extends EventObject {
    private static final long serialVersionUID = 1L;
    protected String msg = null;

    public ApplicationEvent(Object arg0) {
        super(arg0);
        this.msg = arg0.toString();
    }
}

继承了java.util.EventObject加入到jdk的事件体系中。

3.2:监听器对象

public class ApplicationListener implements EventListener {

    void onApplicationEvent(ApplicationEvent event) {
        System.out.println(event.toString());
    }
}

继承了java.util.EventListener加入到了jdk的时间体系中。

3.3:容器刷新事件

public class ContextRefreshEvent extends ApplicationEvent{
    private static final long serialVersionUID = 1L;
    public ContextRefreshEvent(Object arg0) {
        super(arg0);
    }
    
    public String toString() {
        return this.msg;
    }
}

3.4:事件发布

public interface ApplicationEventPublisher {
    void publishEvent(ApplicationEvent event);
    void addApplicationListener(ApplicationListener listener);
}

实现类:

public class SimpleApplicationEventPublisher implements 
ApplicationEventPublisher{
    List<ApplicationListener> listeners = new ArrayList<>();
    @Override
    public void publishEvent(ApplicationEvent event) {
        for (ApplicationListener listener : listeners) {
            listener.onApplicationEvent(event);         
        }
    }
    @Override
    public void addApplicationListener(ApplicationListener listener) {
        this.listeners.add(listener);
    }
}

负责维护监听器和发布事件。

4:测试

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="bbs" class="com.hc.minispring.ioc.four_beanfactory_and_event.test.BaseBaseService" init-method="init">
        <property type="com.hc.minispring.ioc.four_beanfactory_and_event.test.AServiceImpl" name="as" ref="aservice"/>
    </bean>
    <bean id="aservice" class="com.hc.minispring.ioc.four_beanfactory_and_event.test.AServiceImpl">
        <constructor-arg type="String" name="name" value="abc"/>
        <constructor-arg type="int" name="level" value="3"/>
        <property type="String" name="property1" value="Someone says"/>
        <property type="String" name="property2" value="Hello World!"/>
        <property type="com.hc.minispring.ioc.four_beanfactory_and_event.test.BaseService" name="ref1" ref="baseservice"/>
    </bean>
    <bean id="baseservice" class="com.hc.minispring.ioc.four_beanfactory_and_event.test.BaseService" init-method="init">
    </bean>

</beans>

测试类:

public class Test1 {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("four_beanfactory_and_event/beans.xml");
	    AService aService;
	    BaseService bService;
		try {
		    bService = (BaseService)ctx.getBean("baseservice");
		    bService.sayHello();
		} catch (BeansException e) {
			e.printStackTrace();
		}
	}

}

运行:

Context Refreshed...
Base Service says hello---four
bean injected by annotation @Autowired run...

Process finished with exit code 0

写在后面

参考文章列表

手把手带你写一个 Mini

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值