一、反射概述
JAVA反射机制是在运行状态中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
通俗的来说:java中的反射和物理学上的反射一样,就像是java类在照镜子,Class对象是镜像,Class对象和java对象是一样的,它可以调用java类中的任意一个方法和属性。有人会疑问为什么又要弄出来一个一模一样的类呢?java类实例化之后不是也可以调用他自己的属性吗?因为Java程序是先编译再运行的,而Class获取的对象可以在运行的时候再加载,可以降低代码的耦合度
二、反射的原理
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
三 、反射的使用
3.1、获取Class对象的三种方式:
3.1.1、new之后使用getClass()获取Class对象
Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
Class stuClass = stu1.getClass();//获取Class对象
3.1. 2、使用静态的class属性获取
Class stuClass2 = Student.class;
3.1. 3、通过Class类的forName()方法获取常用
Class stuClass3 = Class.forName("com.bean.Student");//括号中是类的全类名(即包名+类名)
3.2、反射的应用
3.2.1、Class对象中一些方法的使用
先写一个接口和两个接口的实现类
BookService 接口
public interface BookService {
public void add();
public void fun();
}
BookServiceImpl实现类
public class BookServiceImpl implements BookService {
//类的属性---存储数据
public String name;
int age;
protected String sex;
private String address;
//类的构造方法---用来构造对象
public BookServiceImpl() {
}
public BookServiceImpl(String name) {
this.name = name;
}
private BookServiceImpl(String name, int age, String sex, String address) {
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
}
BookDao bookDao=new BookDaoImpl();
//功能方法---完成一些程序或者功能
@Override
public void add() {
System.out.println("BookServiceImpl...add");
bookDao.add();
}
public void fun(){
System.out.println("BookServiceImpl...fun");
}
}
BookServiceVip实现类
public class BookServiceVip implements BookService {
BookDao bookDao=new BookDaoImpl();
@Override
public void add() {
System.out.println("BooKServiceVip...add");
bookDao.add();
}
public void fun(){
System.out.println("BookServiceImpl...fun");
}
}
Class对象中常用的方法
·static Class<?>forName(String className):返回与带有给定字符串名的类或接口相关联的 Class 对象。
·static Class<?>forName(String name, boolean initialize, ClassLoader loader):使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。
· ClassLoadergetClassLoader():返回该类的类加载器。
·Constructor<T>getConstructor(Class<?>... parameterTypes):返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
·Constructor<?>[]getConstructors():返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
·Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
·Constructor<?>[]getDeclaredConstructors():返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
·FieldgetDeclaredField(String name):返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
·Field[]getDeclaredFields(): 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
·MethodgetDeclaredMethod(String name, Class<?>... parameterTypes):返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
·Method[]getDeclaredMethods(): 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
·FieldgetField(String name): 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
·Field[]getFields(): 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
·MethodgetMethod(String name, Class<?>... parameterTypes): 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
·Method[]getMethods():返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
在测试类Class中的一些常用的方法
public class Test01 {
public static void main(String[] args) throws Exception {
//通过全类名加载类的Class对象
Class cla = Class.forName("com.service.impl.BookServiceImpl");
//Class对象可以认为是类的手术刀,可以解刨类里面的东西--属性、构造器、方法
Field[] fields = cla.getFields(); //只能获取public修饰的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-------------");
Field[] fields1 = cla.getDeclaredFields(); //获取所有属性
for (Field field : fields1) {
System.out.println(field);
}
System.out.println("======================");
Constructor[] constructors = cla.getConstructors();//获取构造该方法(public修饰的方法)
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------------");
Constructor[] constructors1 = cla.getDeclaredConstructors();//获取所有的构造方法
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
System.out.println("======================");
Method[] methods = cla.getMethods();//获取所有public修饰的方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-------------");
Method[] methods1 = cla.getDeclaredMethods();//获得类的所有方法。包括private 声明的和继承类
for (Method method : methods1) {
System.out.println(method);
}
}
}
Spring框架特点
1.方便解耦、简化开发
通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造 成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写 代码,可以更专注于上层的应用。
2.AOP编程支持
通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通 过AOP轻松应付。
3.声明式事务的支持
在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的 管理,提高开发效率和质量。
4.方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而 是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。
5.方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对 各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。
6.降低Java EE API的使用难度
Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通 过Spring的简易封装,这些Java EE API的使用难度大为降低。
7.Java 源码是经典学习范例
Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对 Java设计模式 灵活运用以及对 Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自 己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。
配置spring的核心文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.zxd.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.zxd.service.impl.BookServiceImpl">
<property name="name" value="唐秋博"></property>
<property name="age" value="20"></property>
<property name="bookDao" ref="bookDao"></property>
</bean>
</beans>
测试方法:
package com.zxd.test;
import com.zxd.service.BookService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 27425 2023/3/24 10:23
* @version 1.0
*/
public class Test01 {
BookService bookService;
@Test
public void Test01(){
//对象的创建由spring框架创建,此处只需要直接问IOC容器要
//通过Class
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("Spring.xml");
bookService = (BookService) context.getBean("bookService");
bookService.save();
}
}
Spring优点:
1.低侵入式设计,代码污染极低
2.独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承 诺
3.Spring的DI机制降低了业务对象替换的复杂性,提高了组件之间的解耦
4.Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好 的复用
5.Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问 6.Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部