【仿写spring之ioc篇】三、检查是否实现了Aware接口并且执行对应的方法

news/2024/5/19 3:31:03 标签: spring, java, 后端, 反射, 代理, Aware

Aware_0">Aware接口

Aware接口中只是设置了对应的set方法,目前只定义了三个Aware

在这里插入图片描述
以BeanNameAware为例

java">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_24">检查Aware接口

java">	/**
     * @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执行实现方法

java">	/**
     * 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是同一个

java">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一下
在这里插入图片描述
主程序中的代码

java">				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);
                }

测试类中的代码

java">/**
 * 测试组件
 *
 * @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());
    }
}

测试结果

在这里插入图片描述


http://www.niftyadmin.cn/n/4993503.html

相关文章

如何创建HttpServletRequest对象

我们常用的就是在Controller层的接口入参时定义&#xff0c;这样我们就能直接用了&#xff0c;如下图&#xff1a; 但是某些情况&#xff0c;我们需要传递这个request 到各种工具类中&#xff0c;传递这个request 相对要麻烦一些&#xff0c; 我们可以不用传递&#xff0c;在…

《信息系统项目管理师教程(第4版)》第17章 采购管理、合同管理 知识点整理,xmind思维导图

已上传采购管理xmind思维导图&#xff0c;需要的同学可以直接下载哦。 一、规划采购管理 二、实施采购 三、控制采购 四、合同管理 4.1 合同类型 4.2 合同管理过程 签订履行变更档案&#xff0c;合同档案管理是整个合同管理的基础&#xff0c;要求采用电脑打印文本&#xff…

动态规划(选择)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 作为队伍的核心&#xff0c;forever97很受另外两个队友的尊敬。 Trote_w每天都要请forever97吃外卖&#xff0c;但很不幸的是宇宙中心forever97所在的学校周围只有3家forever97爱吃的外卖。 如果T…

50ETF期权开户平台(0门槛期权开户指南)

50ETF期权开户平台比较好的有&#xff1a;期权馆&#xff0c;期权科普馆&#xff0c;小熊期权&#xff0c;期权酱&#xff0c;财顺财经&#xff0c;财顺期权等&#xff0c;都是国内前十的期权分仓平台&#xff0c;下文为大家结算50ETF期权开户平台&#xff08;0门槛期权开户指南…

复杂性分析与算法设计:解锁计算机科学的奥秘

文章目录 算法复杂性分析的基本概念时间复杂度空间复杂度 常见的算法设计策略1. 分治法2. 贪心法3. 动态规划 算法设计的实际应用1. 网络路由2. 图像处理3. 人工智能 算法的选择和性能分析结论 &#x1f389;欢迎来到数据结构学习专栏~复杂性分析与算法设计&#xff1a;解锁计算…

异或和大小比较类问题——抓住最高位:CF1863F

https://codeforces.com/contest/1863/problem/F 因为有等于&#xff0c;所以考虑异或和为0的合法区间&#xff0c;它可以随意切现在考虑切开后左边大于右边&#xff0c;可以发现左右边最高位可以互相抵消&#xff0c;似乎不太可做&#xff1f;此时可以换个考虑&#xff0c;考…

Unity 切换场景后场景变暗

问题 Unity版本&#xff1a;2019.4.34f1c1 主场景只有UI&#xff0c;没有灯光&#xff0c;天空盒&#xff1b;其他场景有灯光和天空盒所有场景不烘焙主场景作为启动场景运行&#xff0c;切换到其他场景&#xff0c;场景变暗某一个场景作为启动场景运行&#xff0c;光影效果正…

虚拟掌控者:快速掌握VMware安装技巧

本章目录 一、VMware是什么&#xff1f;二、下载1、方式一&#xff08;直接下载&#xff09;1.1、点击产品1.2、下滑选择Workstation Pro1.3、下滑选择试用版1.4、选择下载对应的环境Windows | Linux 2、方式二 &#xff08;进行登录下载&#xff09;2.1、进入官方地址&#xf…