Loading

java oop第11章_反射、BaseDao的进一步改造

 

引言:从Java5开始,Java中引用了一个新的概念反射,当程序运行时,能动态感知到程序中拥有的所以信息,这个获取信息的过程是采用反射机制来完成。

一、       Class类:

  Class类用于保存Java程序中所有接口、类、数组所编写的所有消息,一旦我们创建以个接口、类、数组时会在Class类中被注册,即保存所有信息。

  当我们需要获取某个接口、类、数组中的信息时就可以先获取他们在Class中注册的对象,通过该对象再调用反射机制提供的一些方法来获取、操作。

 

 

二、       获取某个接口、类或数组在Class中注册的对象:

  1. 1.     通过调用getClass()方法获取:

Grade grade = new Grade();

Class gradeClss = grade.getClass();

  1. 2.     通过接口、类访问class静态属性获取:

Class studentClass = Student.class;

  1. 3.     通过全类名的方式获取:

Class driverClass = Class.forName("com.mysql.jdbc.Driver");

 

三、       通过Class对象调用反射机制提供的方法完成操作:

   1、获取属性、方法、接口、父类等;

/**
     * 通过反射获取Grade的属性
     * 若调用带有getDeclared开头的方法,表示不管该资源是否是私有的,全部都能访问
     */
    @Test
    public void testGetFieds() {
        Class clazz = Grade.class;
        //Field[] fiels = clazz.getFields();
        Field[] fiels = clazz.getDeclaredFields();
        for (Field field : fiels) {
            System.out.println(field.getName());
        }
    }
    
    /**
     * 通过反射获取Grade的属性                            
     * 若调用带有getDeclared开头的方法,表示不管该资源是否是私有的,全部都能访问
     */
    @Test
    public void testGetMedthods() {
        Class clazz = Grade.class;
        //Field[] fiels = clazz.getFields();
        Method[] medthods = clazz.getDeclaredMethods();
        clazz.getSuperclass();
        for (Method medthod : medthods) {
            System.out.println(medthod.getName());
        }
    }

   2、通过反射创建对象并调用方法:使用用反射创建一个对象StudentDao的实现类对象,并通过该对象调用其中的selectStudentAll()方法。

@Test
public void studentDaoObject() throws Exception {
    Class clazz = StudentDaoImpl.class;
    Object studentDaoImpl = (StudentDaoImpl)clazz.newInstance();
List
<Student> list = ((StudentDao) studentDaoImpl).selectStudentAll();
for (Student student : list) { System.out.println(student); } }

 

 

四、       Java中默认的几个类加载器:

Java虚拟机(jvm)启动时就会自动启动几个类加载器,它们分别是“系统类加载器”、“扩展类加载器”、“根类加载器”,我们也可以获取到前两个加载器,而“根类加载器”不允许获取。

  1)    “根类加载器”:当JVM启动时加载一些必要的类,如java.lang包中的类。

  2)    系统类加载器”:在JVM启动时加载sun公司提供的一些类,如:Java.util.Date。

  3)    “扩展类加载器”:在JVM启动时加载一些第三方提供的一些类,如:com.mysql.jdbc.Driver。

/**
     * 练习类加载器的使用
     * 在练习过程中将 获取Java类中的几个类加载器
     * 系统、扩展加载器可以获取,根类加载器不允许获取。
     */
    @Test
    public void testClassLoader() {
        //获取系统类加载器:
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        System.out.println("系统类加载器:" + classLoader);
        
        //获取扩展类加载器
        ClassLoader extendClassLoader = ClassLoader.getSystemClassLoader().getParent();
        System.out.println("扩展类加载器:" + extendClassLoader);
        
        //试图获取根类加载器,实则无法获取到
        ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent().getParent();
        System.out.println("试图获取根类加载器:" + bootClassLoader);
        
    }

 

五、       通过类加载器加载放置在src下的资源:

  放置在src下的资源不能像放置在webroot下的资源直接通过“/XXX”来获取,而要通过类加载器才能获取到。

  案例:针对BaseDao的改造:

  需要将写死在BaseDao中连接数据库的4个参数:驱动(driverClass)、url(jdbcurl)、用户名(user)、密码(password)移到一个属性文件(db.properties)中,在  BaseDao中通过类加载器将db.properties加载进来,还需要一个properties的工具类来读取db.properties中的内容。

 

db.properties  :在项目下新建一个Source Folder文件夹,名为config,在文件夹下新建名为db.properties的file,如果以后要修改数据库信息,就可以直接在这个文件中进行修改。

driverClass = com.mysql.jdbc.Driver
jdbcurl = jdbc:mysql://127.0.0.1:3306/myschool39
user = root
password = root

#driverClass = oracle.jdbc.driver.OracleDriver
#jdbcurl = jdbc:oracle:thin:@127.0.0.1:1521:orcl
#user = user39
#password = root

#driverClass = com.microsoft.sqlserver.jdbc.SQLServerDriver
#jdbcurl = jdbc:sqlserver://127.0.0.1:1433;databaseName = sqlserver
#user = sa
#password = root

BaseDao.java

package com.oop.util;

import java.io.InputStream;
/*
 * BaseDao类定义三个属性(Connection、PreparedStatement、ResultSet类型)和
 * 两个方法:获取连接的方法getConnection()、关闭资源的方法closeAll。
 */
import java.sql.*;
import java.util.Properties;

public class BaseDao {
    // 三个属性
    protected InputStream inputStream = null;
    
    protected Connection ct = null;
    protected PreparedStatement pst = null;
    protected ResultSet rs = null;

    // 获取连接
    protected Connection getConnection() {
        try {
            
            //0、从db.properties属性文件中获取连接数据库的四个参数值
            //  com/oop/util/db.properties  如果属性文件在util包下的使用方法
            
            inputStream =  this.getClass().getClassLoader().getResourceAsStream("db.properties");
            Properties properites = new Properties();
            properites.load(inputStream);
String driverClass
= properites.getProperty("driverClass"); String jdbcurl = properites.getProperty("jdbcurl"); String user = properites.getProperty("uset"); String password = properites.getProperty("password"); // 1---加载(注册)驱动:指定需要链接的是哪种数据库管理系统 /* * 用Class类直接调用forName(String className)方法 * 获取Driver类在Class中注册的对象,通过该对象可以利用“反射机制”获取到Driver类中的所有信息。 */ Class.forName(driverClass); // 2---获取与数据库链接:需要指定URL(jdbc:mysql://127.0.0.1:3306/数据库名)、user、password。 // 返回值需要用一个connection接口实现类的对象ct接收 ct = DriverManager.getConnection(jdbcurl, user, password); } catch (Exception e) { e.printStackTrace(); } return ct; } //关闭资源 protected void closeAll() { try { if (rs != null) { rs.close(); } if (pst != null) { pst.close(); } if (ct != null) { ct.close(); } if (inputStream != null) { inputStream.close(); } } catch (Exception e) { e.printStackTrace(); } } }

 

 

posted @ 2019-10-31 09:20  dBevil  阅读(410)  评论(0编辑  收藏  举报