Spring中大量使用了反射机制,那么究竟是什么地方使用了呢?
一 反射源头Class类
对类的概念我们已经非常熟悉了。比如可以有Student这个类,Person这个类。但是我们要知道,有一个叫Class的类,它是反射的源头。
正常方式:通过完整的类名—>通过new实例化—>取得实例化对象
反射方式:实例化对象—>getClass()方法—>通过完整的类名
一个简单的例子:
package cn.classes;
public class OneClass {
}
package cn.test;
import cn.classes.OneClass;
public class Test {
public static void main(String[] args) {
OneClass c = new OneClass();
System.out.println(c.getClass().getName());
}
}
输出结果:cn.classes.OneClass
我们需要使用反射,就要获得Class这个类,有三种方法:
package cn.classes;
public class OneClass {
}
import cn.classes.OneClass;
public class Test {
public static void main(String[] args) {
Class<?> c1 = null;
Class<?> c2 = null;
Class<?> c3 = null;
try
{
// 方法一:forName(重要)
c1 = Class.forName("cn.classes.OneClass");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
// 方法二
c2 = new OneClass().getClass();
// 方法三
c3 = OneClass.class;
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
}
}
输出结果:cn.classes.OneClass
二 利用Class这个类实例化类
①无参构造
package cn.classes;
public class Person {
private String name;
private int age;
.............省略getter,setter..............
@Override
public String toString()
{
return "Person [name=" + name + ", age=" + age + "]";
}
}
package cn.test;
import cn.classes.Person;
public class Test
{
// 这样做必须在类中有一个空构造方法
public static void main(String[] args)
{
Class<?> c = null;
try
{
c = Class.forName("cn.classes.Person");
Person p = (Person)c.newInstance();
p.setName("xy");
p.setAge(20);
System.out.println(p);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
②有参构造
package cn.classes;
public class Person
{
private String name;
private int age;
public Person(Stringname,int age){
this.name = name;
this.age = age;
}
.............省略getter,setter..............
@Override
public String toString()
{
return "Person [name=" + name + ", age=" + age + "]";
}
}
package cn.test;
import java.lang.reflect.Constructor;
import cn.classes.Person;
public class Test
{
// 如果没有一个空构造方法
public static void main(String[] args)
{
Class<?> c = null;
try
{
c = Class.forName("cn.classes.Person");
Constructor<?> con = c.getConstructors(String.class,int.class);
Person p = (Person)con.newInstance("xy",20);
System.out.println(p);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
三 Spring中使用Class实例化
bean.xml
<bean id="id" class="com.xy.Student" />
Spring将采用的代码创建代码Java实例
Class c = Class.forName("com.xy.Student");
Object bean = c.newInstance();
四 Class类调用方法
package cn.classes;
public class Person
{
public void add()
{
System.out.println("add");
}
public void addWithParameters(String name, int age)
{
System.out.println("add带参数方法" + name + age);
}
}
package cn.test;
import java.lang.reflect.Method;
public class Test
{
public static void main(String[] args)
{
Class<?> c1 = null;
try
{
c1 = Class.forName("cn.classes.Person");
// 不带参数的方法调用
Method m = c1.getMethod("add");
m.invoke(c1.newInstance());
// 带参数方法调用
Method m1 = c1.getMethod("addWithParameters", String.class, int.class);
m1.invoke(c1.newInstance(), "xy", 22);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
五 Class获得getter,setter方法
Class这个类可以获得类的很多信息,比如获得该类的接口,构造函数,属性,方法等。我们来看如何获得getter,setter方法。
package cn.classes;
public class Person
{
private String name;
private int age;
省略getter,setter
}
package cn.test;
import java.lang.reflect.Method;
public class Test
{
public static void main(String[] args)
{
Class<?> c1 = null;
Object obj = null;
try
{
c1 = Class.forName("cn.classes.Person");
obj = c1.newInstance();
setter(obj, "name", "xy", String.class);
setter(obj, "age", 20, int.class);
getter(obj, "name");
getter(obj, "age");
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* @param obj:要操作的对象
* @param att:要操作的属性
* @param value:要设置的属性内容
* @param type:要设置的属性类型
*/
public static void setter(Object obj, String att, Object value, Class<?> type)
{
try
{
// 得到setter方法
Method m = obj.getClass().getMethod("set" + initStr(att), type);
m.invoke(obj, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* @param obj:要操作的对象
* @param att:要操作的属性
*/
public static void getter(Object obj, String att)
{
try
{
// 得到getter方法
Method m = obj.getClass().getMethod("get" + initStr(att));
System.out.println(m.invoke(obj));
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static String initStr(String oldStr)
{
String newStr = oldStr.substring(0, 1).toUpperCase() + oldStr.substring(1);
return newStr;
}
}
六 Spring调用getter,setter方法
我们以setter注入例子
bean.xml
<bean id="id" class="com.xy.Student">
<property name="stuName" value="xy" />
</bean>
Spring将采用的代码创建代码Java实例,并注入值:
Class c = Class.forName("com.xy.Student");
Object bean = c.newInstance();
通过一些操作获取对stuName对应的setter方法名
String setname = "set" + "StuName";
Method method = c.getMehod(setname,String.Class);
method.invoke(bean,"xy");
这样就完成了最基本的注入操作。当然,Spring还可以通过构造函数进行注入。这样就参考第二点有参构造的Class的使用。
Class还可以访问Annotation,这样就Spring使用注解的时候,可以完成注入的功能。
七 总结
反射的内容还是很多的,需要系统的学习。当然,Spring也是。
JAVA技术交流群 532101200
相关推荐
3. **反射机制**:在AOP动态代理中,反射机制扮演着重要角色。通过反射,我们可以动态获取类的信息,包括类的字段、方法等,并能够在运行时动态地调用方法。在创建代理对象和处理方法调用时,都会用到反射。 4. **...
在这个特定的"spring IOC反射装载bean"的主题中,我们将深入探讨Spring如何通过XML配置文件来加载和管理Bean,并利用Java的反射机制来实例化这些Bean。 首先,Spring容器通过读取XML配置文件来获取Bean的定义。这些...
而在Spring中,控制权反转了,容器负责管理对象及其依赖关系,而不是由对象自己管理。这样做的好处包括提高了代码的可测试性、降低了耦合度和提高了组件的可重用性。Spring通过XML配置、注解或Java配置来实现IOC,...
* 实现依赖注入:Java 反射机制可以用来实现依赖注入,例如在 Spring 框架中。 * 实现 AOP:Java 反射机制可以用来实现面向方面编程(Aspect-Oriented Programming),例如在 Spring 框架中。 * 实现动态代理:Java ...
本文详细介绍了Java反射机制的概念与核心API(包括Class、Constructor、Method、Field等)。此外深入探讨了Java反射的实际用途:诸如动态加载、创建对象以及操作其方法、字段。并通过实战编码示范展示这一系列功能的...
Spring中ApplicationContext加载机制 ApplicationContext 是 Spring 框架中的核心组件之一,负责加载和管理应用程序中的 Bean 对象。在 Web 应用程序中,ApplicationContext 的加载机制是非常重要的, Spring 提供...
反射机制在Java中的应用非常广泛,不仅可以用于实现框架层面的功能,如Spring框架的依赖注入,还可以用于简化代码,提高程序的扩展性和维护性。 ##### 在Android开发中的应用 在Android开发中,反射机制同样有着...
在Java编程中,Spring框架是应用最广泛的IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)容器。这篇博客"使用反射和注解模拟Spring的依赖注入"探讨了如何通过基本的Java特性来实现...
本文将深入探讨Java反射机制的原理及其在实际开发中的应用。 首先,我们要理解什么是反射。反射是指在运行时,程序能够获取关于类、接口、字段和方法等信息,并且能够动态地调用方法、创建对象的能力。在Java中,`...
- **框架开发**:如Spring框架中的依赖注入就是通过反射实现的。 - **测试工具**:可以通过反射获取类的私有成员,进行测试。 - **插件机制**:动态加载和执行外部组件。 #### 四、Java反射机制的优势与局限性 ...
通过深入理解Spring中的反射机制,开发者可以更有效地利用Spring框架,提高代码的可维护性和可扩展性。同时,反射也带来了一些潜在的问题,比如性能开销和安全风险,因此在实际使用中需要适度控制和优化。总的来说,...
在Spring中,可以通过ApplicationContext接口的实现类,比如ClassPathXmlApplicationContext,来加载位于classpath中的配置文件。例如,创建一个ApplicationContext对象的代码如下: ```java ApplicationContext ...
4. 框架开发:Spring框架就是反射机制的一个典型应用,它利用反射来实现依赖注入,提高代码的可测试性和解耦。 5. 运行时调用未知方法:例如,在处理用户输入或配置文件时,可以使用反射调用指定的方法。 使用反射...
- **框架设计**:Spring框架利用反射机制实现依赖注入等功能。 - **单元测试**:JUnit等测试框架利用反射机制访问私有方法等。 - **热插拔式架构**:动态加载插件或模块,实现软件的扩展。 总结而言,Java反射机制...
《反射机制在Android开发中的应用》 随着Android系统在智能手机领域的普及,越来越多的开发者投身于Android应用开发。至2013年,Android市场应用数量已达到80万,但在开发过程中,有时会遇到API限制导致优秀的软件...
这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在框架和库的开发中,如Spring框架,它大量利用了反射机制。 在上述的示例中,`Util` 类的 `convertStr2ServiceBean` 方法展示了如何通过反射来创建对象...
Spring 的事务管理机制使得应用程序可以在数据库和其他资源中执行事务。 Spring 的事务管理机制提供了多种方式来管理事务,包括编程式事务和声明式事务。 Spring 的 JDBC 模块提供了多种方式来访问数据库,包括 ...
在Spring中,反射被广泛用于实现依赖注入,通过`Class.newInstance()`或`Constructor.newInstance()`方法创建对象,然后根据注解或配置文件设置其属性。 代理,又分为静态代理和动态代理。静态代理是在编译时期就...
Java反射机制在实际开发中有着广泛的应用,例如: 1. **动态代理**:利用反射可以创建动态代理类,这对于实现AOP(面向切面编程)非常有用。 2. **框架开发**:许多Java框架,如Spring、Hibernate等,大量使用了反射...