14-@Autowired处理

简单的注入

准备bean

static class Bean1 {

    @Autowired
    private Bean2 bean2;

    @Autowired
    public void setBean2(Bean2 bean2) {
        this.bean2 = bean2;
    }

    @Autowired
    private Optional<Bean2> bean3;

    @Autowired
    private ObjectFactory<Bean2> bean4;

    @Autowired
    @Lazy
    private Bean2 bean5;

}


@Component("bean2")
static class Bean2 {
}

处理注入

@Configuration
public class TestAutowired {

    @SneakyThrows
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestAutowired.class);
        DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();

        // 1. 根据成员变量类型注入
        DependencyDescriptor dd1 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean2"), true);
        System.out.println(beanFactory.doResolveDependency(dd1, "bean1", null, null));

        // 2. 根据方法的入参类型注入   方法名 + 参数索引
        DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(Bean1.class.getMethod("setBean2", Bean2.class), 0), true);
        System.out.println(beanFactory.doResolveDependency(dd2, "bean1", null, null));

        // 3. Optional成员变量注入
        DependencyDescriptor dd3 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean3"), true);
        System.out.println("bean3类型:" + dd3.getDependencyType());
        if (dd3.getDependencyType() == Optional.class) {
            // 内嵌级别+1 获取真实类型
            dd3.increaseNestingLevel();
            System.out.println("内嵌级别+1后:" + dd3.getDependencyType());
            Object ret = beanFactory.doResolveDependency(dd3, "bean1", null, null);
            System.out.println(Optional.ofNullable(ret));
        }

        // 4. ObjectFactory成员变量注入
        DependencyDescriptor dd4 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean4"), true);
        System.out.println("bean4类型:" + dd4.getDependencyType());
        if (dd4.getDependencyType() == ObjectFactory.class) {
            // 内嵌级别+1 获取真实类型
            dd4.increaseNestingLevel();
            System.out.println("内嵌级别+1后:" + dd4.getDependencyType());
            Object ret = beanFactory.doResolveDependency(dd4, "bean1", null, null);
            ObjectFactory objectFactory = new ObjectFactory() {
                @Override
                public Object getObject() throws BeansException {
                    return ret;
                }
            };
            System.out.println(objectFactory.getObject());
        }

        // 5. @Lazy处理
        DependencyDescriptor dd5 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean5"), true);
        // 解析@Value、@Lazy
        ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
        resolver.setBeanFactory(beanFactory);

        Object proxy = resolver.getLazyResolutionProxyIfNecessary(dd5, "bean1");
        System.out.println(proxy);
        // 生成的对象是动态代理
        System.out.println(proxy.getClass());

    }
}

复杂的注入

准备bean

interface Service {
}

@Component("service1")
static class Service1 implements Service {
}

@Primary
@Component("service2")
static class Service2 implements Service {
}

@Component("service3")
static class Service3 implements Service {
}

interface DAO<T> {
}

static class Student {
}

static class Teacher {
}

@Component("DAO1")
static class DAO1 implements DAO<Student> {
}

@Component("DAO2")
static class DAO2 implements DAO<Teacher> {
}

目标类

static class Target {
    @Autowired
    private Service[] serviceArr;
    @Autowired
    private List<Service> serviceList;
    @Autowired
    private ConfigurableApplicationContext applicationContext;
    @Autowired
    private DAO<Teacher> dao;  // DAO2
    @Autowired
    @Qualifier("service2")
    private Service service;
}

注入-数组

@SneakyThrows
private static void testArray(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor serviceArr = new DependencyDescriptor(Target.class.getDeclaredField("serviceArr"), true);
    // 当前属性是一个数组
    //System.out.println(serviceArr.getDependencyType());
    if (serviceArr.getDependencyType().isArray()) {
        Class<?> componentType = serviceArr.getDependencyType().getComponentType();
        System.out.println("数组类的真实类型:" + componentType);
        // 根据类型从当前容器或者父级容器中获取bean名字
        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, componentType);
        List<Object> retBeans = new ArrayList<>();
        for (String beanName : beanNames) {
            System.out.println("findBean=>" + beanName);
            // 从容器中根据beanName获取bean
            Object ret = serviceArr.resolveCandidate(beanName, componentType, beanFactory);
            retBeans.add(ret);
        }
        // 类型转换  list->数组
        Object ret = beanFactory.getTypeConverter().convertIfNecessary(retBeans, serviceArr.getDependencyType());
        System.out.println("最终注入的数组:" + ret);
    }
}

注入-list

@SneakyThrows
private static void testList(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor serviceList = new DependencyDescriptor(Target.class.getDeclaredField("serviceList"), true);
    if (serviceList.getDependencyType() == List.class) {
        Class<?> resolveType = serviceList.getResolvableType().getGeneric().resolve();
        System.out.println("list的真实类型:" + resolveType);
        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, resolveType);
        List<Object> ret = new ArrayList<>();
        for (String beanName : beanNames) {
            Object bean = serviceList.resolveCandidate(beanName, resolveType, beanFactory);
            ret.add(bean);
        }
        System.out.println(ret);
    }
}

注入-ApplicationContext

@SneakyThrows
private static void testApplicationContext(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor applicationContext = new DependencyDescriptor(Target.class.getDeclaredField("applicationContext"), true);

    Field resolvableDependencies = DefaultListableBeanFactory.class.getDeclaredField("resolvableDependencies");
    resolvableDependencies.setAccessible(true);
    Map<Class<?>, Object> resolvableDependencyMap = (Map<Class<?>, Object>) resolvableDependencies.get(beanFactory);
    resolvableDependencyMap.forEach((k, v) -> {
        // 几个核心类没有放在一级缓存中,而是放在了resolvableDependencies成员变量中  分别是:ResourceLoader、ApplicationEventPublisher、ApplicationContext以及BeanFactory
        System.out.println("key: " + k + ", value:" + v);
    });


    for (Map.Entry<Class<?>, Object> entry : resolvableDependencyMap.entrySet()) {
        // 左边类型   =  右边类型    即 dependencyType能否复制给 Key
        if (entry.getKey().isAssignableFrom(applicationContext.getDependencyType())) {
            System.out.println("找到了applicationContext:" + entry.getValue());
            break;
        }
    }

}

注入-泛型

@SneakyThrows
private static void testGeneric(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor dao = new DependencyDescriptor(Target.class.getDeclaredField("dao"), true);
    Class<?> dependencyType = dao.getDependencyType();

    // @Value @Lazy 判断@Autowired所需要的类型是否与某个BeanDefinition匹配()
    ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
    resolver.setBeanFactory(beanFactory);

    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, dependencyType);
    for (String beanName : beanNames) {
        System.out.println("找到beanName:" + beanName);

        BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
        if (resolver.isAutowireCandidate(new BeanDefinitionHolder(beanDefinition, beanName), dao)) {
            System.out.println("当前beanName:" + beanName + "匹配");
            System.out.println(dao.resolveCandidate(beanName, dependencyType, beanFactory));
        } else {
            System.out.println("当前beanName:" + beanName + "不匹配");
        }
    }

}

注入-@Qualifier

@SneakyThrows
private static void testQualifier(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor service = new DependencyDescriptor(Target.class.getDeclaredField("service"), true);
    Class<?> dependencyType = service.getDependencyType();

    // @Value @Lazy 判断@Autowired所需要的类型是否与某个BeanDefinition匹配(范型、@Qualifier)
    ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
    resolver.setBeanFactory(beanFactory);

    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, dependencyType);
    for (String beanName : beanNames) {
        System.out.println("找到beanName:" + beanName);

        BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
        if (resolver.isAutowireCandidate(new BeanDefinitionHolder(beanDefinition, beanName), service)) {
            System.out.println("当前beanName:" + beanName + "匹配");
            System.out.println(service.resolveCandidate(beanName, dependencyType, beanFactory));
        } else {
            System.out.println("当前beanName:" + beanName + "不匹配");
        }
    }

}

目标类

static class Target2 {
    @Autowired
    private Service service;

    @Autowired
    private Service service3;
}

注入-@Primary

@SneakyThrows
private static void testPrimary(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor service = new DependencyDescriptor(Target2.class.getDeclaredField("service"), true);
    Class<?> dependencyType = service.getDependencyType();

    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, dependencyType);
    for (String beanName : beanNames) {
        System.out.println("找到beanName:" + beanName);

        BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
        if (beanDefinition.isPrimary()) {
            System.out.println("当前beanName:" + beanName + "匹配");
            System.out.println(service.resolveCandidate(beanName, dependencyType, beanFactory));
        } else {
            System.out.println("当前beanName:" + beanName + "不匹配");
        }
    }

}

注入-byName

@SneakyThrows
private static void testName(DefaultListableBeanFactory beanFactory) {
    DependencyDescriptor service3 = new DependencyDescriptor(Target2.class.getDeclaredField("service3"), true);
    Class<?> dependencyType = service3.getDependencyType();

    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, dependencyType);
    for (String beanName : beanNames) {
        System.out.println("找到beanName:" + beanName);
        if (beanName.equals(service3.getDependencyName())) {
            System.out.println("当前beanName:" + beanName + "匹配");
            System.out.println(service3.resolveCandidate(beanName, dependencyType, beanFactory));
        } else {
            System.out.println("当前beanName:" + beanName + "不匹配");
        }
    }

}
  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这段代码是一个基于Spring框架开发的文件上传的控制器代码。以下是对代码的解释: 1. `@RestController`:该注解表示这是一个控制器类,用于接收和处理用户的请求,并返回数据给客户端。 2. `@Autowired`:该注解用于自动注入依赖对象,这里注入了MenusService类的实例。 3. `@Qualifier("menusService")`:该注解用于指定要注入的具体实现类的名称,这里指定了menusService。 4. `@RequestMapping("upload")`:该注解指定了处理文件上传请求的URL路径。 5. `menusService.insert(menus)`:调用MenusService类的insert方法来插入菜单信息。 6. `file.getOriginalFilename()`:获取上传文件的原始文件名。 7. 如果上传文件名为空,直接返回到 "menus_add.jsp" 页面。 8. `request.getServletContext().getRealPath("/public/img")`:获取文件上传保存的路径。 9. `File realPath = new File(path)`:创建一个文件对象,表示文件上传保存的实际路径。 10. 如果路径不存在,则创建该路径。 11. `InputStream is = file.getInputStream()`:获取上传文件的输入流。 12. `OutputStream os = new FileOutputStream(new File(realPath,uploadFilename))`:创建一个文件输出流,用于将上传文件写入到指定路径下。 13. 使用循环读取输入流中的数据,并将数据写入输出流中,实现文件的上传。 14. 关闭输入流和输出流。 15. 返回 "/admin/main",表示文件上传成功后跳转到管理员主页。 这段代码实现了文件上传的功能,将上传的文件保存到指定路径下,并将菜单信息插入到数据库中。成功上传后,跳转到管理员主页。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

层巅余落日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值