spring java反射机制_番外 01:Spring IoC 实现原理简析,Java的反射机制,通过类名创建对象...

转载请注明来源 赖赖的博客

前景概要

在 01 走进Spring,Context、Bean和IoC 中,我们看到了强大的Spring通过ApplicationContext实现了bean工厂(也就是对象工厂),那究竟是怎么实现的呢,本次给大家写一个小Demo展现其原理;

Spring bean的调用方式和配置方式

(详情可以查看 01 走进Spring,Context、Bean和IoC 这一课程)此处仅贴出代码,如果已经看过 01 走进Spring,Context、Bean和IoC 这一课,可以直接跳过前景概要。

运行App.java输出结果如下

hello

App.java

package me.laiyijie.demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import me.laiyijie.demo.service.AccountService;

/**

* Hello

*

*/

public class App {

public static void main(String[] args) {

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("root-context.xml");

AccountService accountService = context.getBean(AccountService.class);

System.out.println(accountService.sayHello());

context.close();

}

}

root-context.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

AccountService.java

package me.laiyijie.demo.service;

public class AccountService {

public String sayHello() {

return "hello";

}

}

pom.xml代码如下

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

me.laiyijie

demo

0.0.1-SNAPSHOT

jar

org.springframework

spring-context

4.3.2.RELEASE

通过类名创建对象

问题引出和分析

在App.java中,调出AccountService用了两步:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("root-context.xml");

AccountService accountService = context.getBean(AccountService.class);

而root-context.xml中配置AccountService实例只用了一行配置

那么问题来了,Spring是如何通过这一行配置文件来创建这个对象的呢?

此处配置文件只提供了一个类的全限定名me.laiyijie.demo.service.AccountService,那么问题就转化成:

如何通过类名创建对象

问题解决

要解决通过类名创建对象的问题就要引入Java的反射机制。

实例:通过类名创建对象

App.java

package me.laiyijie.demo;

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

import me.laiyijie.demo.service.AccountService;

public class App {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,

InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

Class clazz = classLoader.loadClass("me.laiyijie.demo.service.AccountService");

Constructor constructor = clazz.getConstructor();

AccountService accountService = (AccountService) constructor.newInstance();

System.out.println(accountService.sayHello());

}

}

没有用到 new AccountService 却成功创建了他的对象并调用其方法。

调用过程如下

通过Thread获取当前的类加载器(ClassLoader)

通过ClassLoader获取me.laiyijie.demo.service.AccountService对应的Class对象

通过Class对象获取构造函数对应的Constructor的对象

通过Contructor对象创建AccountService对象

调用sayHello方法

hello

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值