目录
1.3.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
1.3.3 引入junit框架(在StringUnitTest操作)
1.4.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
1.6 Junit框架的常见注解(Junit4.XXX版本)
1.6.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
1.7 Junit框架的常见注解(Junit5.XXX版本)
3.1.2 注解MyTest2(不要复制 MyTest1,我复制发现有问题)
前言:单元测试Junit框架入门、反射、注解、动态代理使用
1 单元测试
1.1 概述

1.2 Junit框架快速入门

1.3 案例1--Junit初体验
1.3.1 准备一个被测类 StringUnit
package com.runa;
public class StringUnit {
public static void printNumber( String name){
if(name == null){
System.out.println(0);
return; //停掉方法
}
System.out.println("名字的长度是:" + name.length());
}
}
1.3.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
package com.runa;
import org.junit.Test;
public class StringUnitTest {
@Test //测试方法
public void testPrintNumber(){
StringUnit.printNumber("春天的菠菜");
StringUnit.printNumber(null);
}
}
1.3.3 引入junit框架(在StringUnitTest操作)
在@Test 注释上按住Alt+ Enter,选择JUnit4

OK
1.3.4 在测试方法执行测试

1.3.5 查看结果

1.4 案例2 -- Junit--断言机制
1.4.1 准备一个被测类 StringUnit
package com.runa;
public class StringUnit {
public static void printNumber( String name){
if(name == null){
System.out.println(0);
return; //停掉方法
}
System.out.println("名字的长度是:" + name.length());
}
/**
* 求字符串的最大索引
*
*/
public static int getMaxIndex(String data){
if(data == null){
return -1;
}
return data.length(); // return data.length() - 1;
}
}
1.4.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
package com.runa;
import org.junit.Assert;
import org.junit.Test;
public class StringUnitTest {
@Test //测试方法
public void testPrintNumber(){
StringUnit.printNumber("春天的菠菜");
StringUnit.printNumber(null);
}
@Test //测试方法
public void testGetMaxIndex(){
int index1 = StringUnit.getMaxIndex(null);
System.out.println(index1);
int index2 =StringUnit.getMaxIndex("春天的菠菜");
// 断言机制,程序员可以通过预测业务方法的结果
Assert.assertEquals("不一致,方法有bug",4,index2);
}
}
1.4.3 执行,查看断言的效果

1.5 执行范围
1.5.1 方法上面执行
执行这个方法测试
1.5.2 类上面执行
执行这个类测试
1.5.3 模块上面执行
执行这个模块的测试
1.6 Junit框架的常见注解(Junit4.XXX版本)

1.6.1 准备一个被测类 StringUnit
package com.runa;
public class StringUnit {
public static void printNumber( String name){
if(name == null){
System.out.println(0);
return; //停掉方法
}
System.out.println("名字的长度是:" + name.length());
}
/**
* 求字符串的最大索引
*
*/
public static int getMaxIndex(String data){
if(data == null){
return -1;
}
return data.length() - 1; // return data.length() - 1;
}
}
1.6.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest
package com.runa;
import org.junit.*;
public class StringUnitTest {
@Before
public void test1(){
System.out.println("每个测试方法开始的执行--------》Before");
}
@After
public void test2(){
System.out.println("每个测试方法结束的执行--------》After");
}
@BeforeClass
public static void test3(){
System.out.println("每个静态方法开始的执行--------》BeforeClass");
}
@AfterClass
public static void test4(){
System.out.println("每个静态方法结束的执行--------》AfterClass");
}
@Test //测试方法
public void testPrintNumber(){
StringUnit.printNumber("春天的菠菜");
StringUnit.printNumber(null);
}
@Test //测试方法
public void testGetMaxIndex(){
int index1 = StringUnit.getMaxIndex(null);
System.out.println(index1);
int index2 =StringUnit.getMaxIndex("春天的菠菜");
// 断言机制,程序员可以通过预测业务方法的结果
Assert.assertEquals("不一致,方法有bug",4,index2);
}
}
1.6.3 执行,查看运行结果

1.7 Junit框架的常见注解(Junit5.XXX版本)

2 反射(了解)
2.1 认识反射、获取类




2.1.1 Student类
package com.reflect;
public class Student {
}
2.1.2 TestClass1主函数
package com.reflect;
public class TestClass1 {
public static void main(String[] args) throws Exception {
// 第一种方式
Class c1 = Student.class;
System.out.println(c1.getName()); // 全类名
System.out.println(c1.getSimpleName());// 简名
// 第二种方式
Class c2 = Class.forName("com.reflect.Student");
System.out.println(c2.getName());
System.out.println(c1 == c2);//三种方式都是同一对象
// 第三种方式
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c3.getName());
System.out.println(c3 == c2); //三种方式都是同一对象
}
}

2.2 获取类的构造器

2.2.1 获取类构造器
2.2.1.1Cat类
package com.reflect;
public class Cat {
private String name;
private int age;
public Cat() {
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.2.1.2 主函数 TestConstructor
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestConstructor {
// 查询全部构造器
@Test
public void testGetConstructors(){
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat.class;
// 获取类的全部构造器
Constructor[] constructors = c.getDeclaredConstructors(); // c.getConstructors(); 只能获取public修饰的的构造器
// 遍历数组中的每个构造器对象
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
}
}
// 查询单个构造器,有参和无参的两种类型
@Test
public void testGetConstructor() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat.class;
// 获取某个构造器,:无参的构造器
Constructor constructor = c.getDeclaredConstructor(); // c.getConstructor(); 只能获取public修饰的
System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
// 获取某个构造器,:有参的构造器
Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class); // c.getConstructor(); 只能获取public修饰的
System.out.println(constructor2.getName() + "--->" + constructor2.getParameterCount()); //查询构造器名和 有几个查询
}
}

2.2.2 获取类构造器的作用
2.2.2.1 Cat类
package com.reflect;
public class Cat {
private String name;
private int age;
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Cat() {
System.out.println("无参数构造器执行了");
}
public Cat(String name, int age) {
System.out.println("有参数构造器执行了");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.2.2.2 主函数 TestConstructor
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestConstructor {
// 查询全部构造器
@Test
public void testGetConstructors(){
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat.class;
// 获取类的全部构造器
Constructor[] constructors = c.getDeclaredConstructors(); // c.getConstructors(); 只能获取public修饰的的构造器
// 遍历数组中的每个构造器对象
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
}
}
// 查询单个构造器,有参和无参的两种类型
@Test
public void testGetConstructor() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat.class;
// 获取某个构造器,:无参的构造器
Constructor constructor = c.getDeclaredConstructor(); // c.getConstructor(); 只能获取public修饰的
System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
constructor.setAccessible(true); // 禁止检查访问权限
Cat cat = (Cat) constructor.newInstance();
System.out.println(cat);
// 获取某个构造器,:有参的构造器
Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class); // c.getConstructor(); 只能获取public修饰的
System.out.println(constructor2.getName() + "--->" + constructor2.getParameterCount()); //查询构造器名和 有几个查询
constructor2.setAccessible(true); // 禁止检查访问权限
Cat cat2 = (Cat) constructor2.newInstance("TOM", 3);
System.out.println(cat2);
}
}

2.3 获取类的成员变量

2.3.1 获取类的成员变量
2.3.1.1 Cat2类
package com.reflect;
public class Cat2 {
public static int a;
public static final String COUNTY = "中国";
private String name;
private int age;
public Cat2() {
System.out.println("无参数构造器执行了");
}
public Cat2(String name, int age) {
System.out.println("有参数构造器执行了");
this.name = name;
this.age = age;
}
public static int getA() {
return a;
}
public static void setA(int a) {
Cat2.a = a;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.3.1.2 主函数
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Field;
public class TestField {
@Test
public void testGetField() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat2.class;
// 2 获取类的全部成员变量
Field[] fields = c.getDeclaredFields(); //c.getFields(); 只能拿public修饰的
// 遍历
for (Field field : fields) {
System.out.println(field.getName() + "类型: " + field.getType());
}
// 3 获取单个成员变量
Field field = c.getDeclaredField("name"); //c.getField(); 只能拿public修饰的
System.out.println(field.getName() + "类型: " + field.getType());
}
}

2.3.2 获取类的成员变量 作用
2.3.2.2 Cat2类
package com.reflect;
public class Cat2 {
public static int a;
public static final String COUNTY = "中国";
private String name;
private int age;
public Cat2() {
System.out.println("无参数构造器执行了");
}
public Cat2(String name, int age) {
System.out.println("有参数构造器执行了");
this.name = name;
this.age = age;
}
public static int getA() {
return a;
}
public static void setA(int a) {
Cat2.a = a;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.3.2.2 主函数
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Field;
public class TestField {
@Test
public void testGetField() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat2.class;
// 2 获取类的全部成员变量
Field[] fields = c.getDeclaredFields(); //c.getFields(); 只能拿public修饰的
// 遍历
for (Field field : fields) {
System.out.println(field.getName() + "类型: " + field.getType());
}
// 3 获取单个成员变量
Field field = c.getDeclaredField("name"); //c.getField(); 只能拿public修饰的
System.out.println(field.getName() + "类型: " + field.getType());
// 赋值
Cat2 cat = new Cat2();
field.setAccessible(true); // 暴力反射,禁止访问控制权限
field.set(cat, "咖啡猫");
System.out.println(cat);
// 取值
String name = (String) field.get(cat);
System.out.println(name);
}
}

2.4 获取类的成员方法

2.4.1 获取类的成员方法
2.4.1.1 Cat3类
package com.reflect;
public class Cat3 {
public static int a;
public static final String COUNTY = "中国";
private String name;
private int age;
public Cat3() {
System.out.println("无参数构造器执行了");
}
public Cat3(String name, int age) {
System.out.println("有参数构造器执行了");
this.name = name;
this.age = age;
}
private void run(){
System.out.println("跑得很快~~~~");
}
public void eat(){
System.out.println("爱吃鱼~~~~");
}
private String eat(String name){
return "最爱吃:" + name;
}
public static int getA() {
return a;
}
public static void setA(int a) {
Cat3.a = a;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.4.1.2 主函数
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Method;
public class TestMethod {
@Test
public void testGetMethods() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat3.class;
// 2 获取全部类的全部成员方法
Method[] declaredMethods = c.getDeclaredMethods();
// 3 遍历
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName() + "-->"
+ declaredMethod.getParameterCount()
+ "-->" + declaredMethod.getReturnType());
}
System.out.println("=================");
// 4 获取某个方法对象
Method run = c.getDeclaredMethod("run"); //拿run方法 无参数
System.out.println(run.getName() + "-->"
+ run.getParameterCount()
+ "-->" + run.getReturnType());
Method eat = c.getDeclaredMethod("eat",String.class); //拿eat方法 有参数
System.out.println(eat.getName() + "-->"
+ eat.getParameterCount()
+ "-->" + eat.getReturnType());
}
}
2.4.2 获取类的成员方法的作用
2.4.2.1 Cat3类
package com.reflect;
public class Cat3 {
public static int a;
public static final String COUNTY = "中国";
private String name;
private int age;
public Cat3() {
System.out.println("无参数构造器执行了");
}
public Cat3(String name, int age) {
System.out.println("有参数构造器执行了");
this.name = name;
this.age = age;
}
private void run(){
System.out.println("跑得很快~~~~");
}
public void eat(){
System.out.println("爱吃鱼~~~~");
}
private String eat(String name){
return "最爱吃:" + name;
}
public static int getA() {
return a;
}
public static void setA(int a) {
Cat3.a = a;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.4.2.2 主函数
package com.reflect;
import org.junit.Test;
import java.lang.reflect.Method;
public class TestMethod {
@Test
public void testGetMethods() throws Exception {
//1 反射第一步:必须先得到这个类的Class对象
Class c = Cat3.class;
// 2 获取全部类的全部成员方法
Method[] declaredMethods = c.getDeclaredMethods();
// 3 遍历
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName() + "-->"
+ declaredMethod.getParameterCount()
+ "-->" + declaredMethod.getReturnType());
}
System.out.println("=================");
// 4 获取某个方法对象
Method run = c.getDeclaredMethod("run"); //拿run方法 无参数
System.out.println(run.getName() + "-->"
+ run.getParameterCount()
+ "-->" + run.getReturnType());
Method eat = c.getDeclaredMethod("eat",String.class); //拿eat方法 有参数
System.out.println(eat.getName() + "-->"
+ eat.getParameterCount()
+ "-->" + eat.getReturnType());
Cat3 cat = new Cat3();
run.setAccessible(true); // 禁止检查访问权限
Object rs = run.invoke(cat); //调用无参数的run方法。用cat对象歘调用的
System.out.println(rs);
Cat3 cat2 = new Cat3();
eat.setAccessible(true); // 禁止检查访问权限
Object rs2 = eat.invoke(cat2,"鱼儿"); //调用有参数的eat方法。用cat对象歘调用的
System.out.println(rs2);
}
}

2.5 作用、变量


2.5.1 Teacher类
package com.reflect;
public class Teacher {
private String name;
private Double salary;
public Teacher() {
}
public Teacher(String name, Double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
2.5.2 Student2类
package com.reflect;
public class Student2 {
private String name;
private int age;
private char sex;
private double height;
private String hobby;
public Student2() {
}
public Student2(String name, int age, char sex, double height, String hobby) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
2.5.3 ObjectFrame类
package com.reflect;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class ObjectFrame {
// 目标:保存任务对象的字段和其数据到文件中去
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("C:\\Users\\cheng\\IdeaProjects\\FirstJava\\opp-junit\\src\\data.txt", true)); // 这个地方没有使用相对路径成功,未找到原因
// obj 是任意对象,到底有多少个字段要保存
Class c = obj.getClass();
String cName = c.getSimpleName();
ps.println("-------------------" + cName + "--------------------");
// 2 从这个类中提取它的全部成员变量
Field[] fields = c.getDeclaredFields();
// 3 遍历
for (Field field : fields) {
// 4 拿到成员变量的命中
String name = field.getName();
// 5 拿到这个成员遍历在对象中的数据
field.setAccessible(true); // 禁止检查访问控制
String value = field.get(obj) + "";
ps.println(name + "=" + value);
}
ps.close();
}
}
2.5.4 主方法
package com.reflect;
import org.junit.Test;
public class TestFrame {
@Test
public void save() throws Exception{
Student2 s1 = new Student2("菠菜", 30, '男' , 175, "实战");
Teacher t1 = new Teacher("黑泽",999.88);
// 需求:把任意对象的字段名和其对应的值等信息,保存到文件当中去
ObjectFrame.saveObject(s1);
ObjectFrame.saveObject(t1);
}
}

3 注解
3.1 概述、自定义注解


3.1.1 注解MyTest1
package com.annotation;
public @interface MyTest1 {
String aaa();
boolean bbb() default true;
String[] ccc();
}
3.1.2 注解MyTest2(不要复制 MyTest1,我复制发现有问题)
package com.annotation;
public @interface MyTest2 {
String value();
}
3.1.3 创建类AnnotationTest1 使用注解
package com.annotation;
@MyTest1(aaa="牛魔王",ccc={"HTML", "JAVA"})
//@MyTest2(value = "孙悟空")
@MyTest2("孙悟空")
public class AnnotationTest1 {
@MyTest1(aaa="牛魔王",bbb = false, ccc={"python", "HTML", "JAVA"})
public void test1(){
}
}
3.2 注解的原理
3.3 元注解



3.4 注解的解析


3.4.1 MyTest4 注解
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
String value();
double aaa() default 100;
String[] bbb();
}
3.4.2 Demo类
package com.annotation;
@MyTest4(value = "孙悟空", aaa = 100.01, bbb = {"紫霞仙子", "春天的菠菜"})
public class Demo {
@MyTest4(value = "白骨精", aaa = 120.01, bbb = {"猪八戒", "春天的菠菜"})
public void test1(){
}
}
3.4.3 AnnotationTest3测试类
package com.annotation;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationTest3 {
@Test
public void parseClass(){
// 1 先获得class对象
Class c = Demo.class;
// 2 解析类上的注解
// 判断类上是否包含某个注解
if(c.isAnnotationPresent(MyTest4.class)){
MyTest4 myTest4 = (MyTest4) c.getDeclaredAnnotation(MyTest4.class);
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
}
@Test
public void parseMethod() throws Exception{
// 1 先获得class对象
Class c = Demo.class;
// 2 再获得方法对象
Method method = c.getDeclaredMethod("test1");
// 2 解析方法上的注解
// 判断方法上是否包含某个注解
if(method.isAnnotationPresent(MyTest4.class)){
MyTest4 myTest4 = (MyTest4) method.getDeclaredAnnotation(MyTest4.class);
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
}
}

3.5 应用场景 -模拟Junit框架设计

3.5.1 MyTest注解
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) //只能注解方法
@Retention(RetentionPolicy.RUNTIME) // 让当前注解可以一直存活
public @interface MyTest {
}
3.5.2 测试方法AnnotationTest4
package com.annotation;
import java.lang.reflect.Method;
public class AnnotationTest4 {
// @MyTest
public void test1(){
System.out.println("==============test1============");
}
@MyTest
public void test2(){
System.out.println("==============test2============");
}
@MyTest
public void test3(){
System.out.println("==============test3============");
}
// @MyTest
public void test4(){
System.out.println("==============test4============");
}
public static void main(String[] args) throws Exception{
AnnotationTest4 a = new AnnotationTest4();
// 启动程序
// 1 得到class对象
Class c = AnnotationTest4.class;
// 2 提取全部成员方法
Method[] methods = c.getDeclaredMethods();
// 3 遍历数组的每个方法,看方法是否存在MyTest注解,存在触发执行
for (Method method : methods) {
if(method.isAnnotationPresent(MyTest.class)){
// 说明当前方法上存在MyTest注解,触发执行
method.invoke(a);
}
}
}
}

4 动态代理
4.1 程序为什么需要代理?代理长什么样?


4.1.1 Star接口
package com.proxy;
public interface Star {
String sing(String name);
void dance();
}
4.1.2 BigStar类
package com.proxy;
public class BigStar implements Star{
private String name;
public BigStar(String name) {
this.name = name;
}
public String sing(String name){
System.out.println(this.name + "正在唱" + name);
return "谢谢!谢谢";
}
public void dance(){
System.out.println(this.name + "正在优雅的跳舞");
}
}
4.1.3 ProxyUtil代理类
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Star creatProxy(BigStar bigStar){
// 参数1 用于指定一个类加载器
// 参数2 指定生成的代理长生么样子,也就是有哪些方法
// 参数3 用来指定生成的代理对象要干什么事情
Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{Star.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理对象要做的事情,会在这里写代码
if(method.getName().equals("sing")){
System.out.println("准备话筒,收钱100万");
}else if(method.getName().equals("dance")){
System.out.println("准备场地,收钱200万");
}
return method.invoke(bigStar, args);
}
});
return starProxy;
}
}
4.1.4 主函数Test
package com.proxy;
public class Test {
public static void main(String[] args) {
BigStar s = new BigStar("春天的菠菜");
Star starProxy = ProxyUtil.creatProxy(s);
String rs = starProxy.sing("柠檬树");
System.out.println(rs);
System.out.println("-------------------");
starProxy.dance();
}
}

4.2 动态代理解决实际问题、掌握使用代理的好处

4.2.1 接口UserService
package com.proxy2;
public interface UserService {
// 登录功能
void login(String loginName, String password) throws Exception;
// 删除用户
void deleteUsers() throws Exception;
// 查询用户,返回数组形式
String[] selectUsers() throws Exception;
}
4.2.2 实现接口类UserServiceImpl
package com.proxy2;
public class UserServiceImpl implements UserService {
@Override
public void login(String loginName, String password) throws Exception {
if("admin".equals(loginName) && "123456".equals(password)){
System.out.println("您登录成功!,欢迎您~~~");
}else{
System.out.println("你登录失败,用户名或密码错误~");
}
}
@Override
public void deleteUsers() throws Exception {
System.out.println("成功删除了10万个用户~");
Thread.sleep(1500);
}
@Override
public String[] selectUsers() throws Exception {
System.out.println("查询出了3个用户");
String[] names = {"邱淑贞", "小玛丽", "黑泽"};
Thread.sleep(500);
return names;
}
}
4.2.3 代理工具类ProxyUtil
package com.proxy2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static UserService createProxy(UserService userService){
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{UserService.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("login") || method.getName().equals("deleteUsers")
|| method.getName().equals("selectUsers")){
long startTime = System.currentTimeMillis();
Object rs = method.invoke(userService, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}else{
Object rs = method.invoke(userService, args);
return rs;
}
}
});
return userServiceProxy;
}
}
4.2.4 主函数Test
package com.proxy2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static UserService createProxy(UserService userService){
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{UserService.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("login") || method.getName().equals("deleteUsers")
|| method.getName().equals("selectUsers")){
long startTime = System.currentTimeMillis();
Object rs = method.invoke(userService, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}else{
Object rs = method.invoke(userService, args);
return rs;
}
}
});
return userServiceProxy;
}
}
262

被折叠的 条评论
为什么被折叠?



