目录
一.单元测试
1.单元测试概述
2.单元测试快速入门
package com.wjh.d1_junit;
/*
测试类
*/
import org.junit.Assert;
import org.junit.Test;
public class TestUserService {
/*
测试方法
注意点:
1.必须是公开的,无参数的,无返回值的方法
2.测试方法必须使用@Test注解标记
*/
@Test
public void testLoginName(){
UserService userService = new UserService();
String rs = userService.loginName("admin", "123456");
//System.out.println(rs);
//进行预期结果的正确性测试:断言.
Assert.assertEquals("你的功能业务可能出现问题", "登录成功", rs);
}
@Test
public void testSelectNames(){
UserService userService = new UserService();
userService.selectNames();
}
}
package com.wjh.d1_junit;
/*
业务方法
*/
public class UserService {
public String loginName(String loginName, String passWord){
if("admin2".equals(loginName) && "123456".equals(passWord)){
return "登录成功";
} else {
return "用户名密码有问题";
}
}
public void selectNames(){
System.out.println(10/0);
System.out.println("查询全部用户名成功!");
}
}
[root]
TestUserService.testLoginName
TestUserService.testSelectNames
java.lang.ArithmeticException: / by zero
at com.wjh.d1_junit.UserService.selectNames(UserService.java:16)
at com.wjh.d1_junit.TestUserService.testSelectNames(TestUserService.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
3.单测试常用注解
package com.wjh.d1_junit;
/*
测试类
*/
import org.junit.*;
public class TestUserService {
//只能修饰实例方法
@Before
public void before(){
System.out.println("=====before方法执行一次=====");
}
@Before
public void after(){
System.out.println("=====after方法执行一次=====");
}
//修饰静态方法
@BeforeClass
public static void beforeClass(){
System.out.println("=====beforeClass方法执行一次=====");
}
@AfterClass
public static void afterClass(){
System.out.println("=====afterClass方法执行一次=====");
}
/*
测试方法
注意点:
1.必须是公开的,无参数的,无返回值的方法
2.测试方法必须使用@Test注解标记
*/
@Test
public void testLoginName(){
UserService userService = new UserService();
String rs = userService.loginName("admin", "123456");
//System.out.println(rs);
//进行预期结果的正确性测试:断言.
Assert.assertEquals("你的功能业务可能出现问题", "登录成功", rs);
}
@Test
public void testSelectNames(){
UserService userService = new UserService();
userService.selectNames();
}
}
=====beforeClass方法执行一次=====
=====after方法执行一次=====
=====before方法执行一次=====
=====after方法执行一次=====
=====before方法执行一次=====
10
查询全部用户名成功!
=====afterClass方法执行一次=====进程已结束,退出代码为 0
二.反射
1.反射概述
2.反射获取类对象
package com.wjh.d2_reflect_class;
/*
目标:
反射第一步:获取Class对象
*/
public class Test {
public static void main(String[] args) throws Exception {
//1.Class类中的静态方法:forName(全限名:包名 + 类名)
Class c = Class.forName("com.wjh.d2_reflect_class.Student");
System.out.println(c); //Student.Class
//class com.wjh.d2_reflect_class.Student
//2.类名.class
Class c1 = Student.class;
System.out.println(c1);
//class com.wjh.d2_reflect_class.Student
//3.对象.getClass() 获取对应类的Class对象
Student s = new Student();
Class c2 = s.getClass();
System.out.println(c2);
//class com.wjh.d2_reflect_class.Student
}
}
class com.wjh.d2_reflect_class.Student
class com.wjh.d2_reflect_class.Student
class com.wjh.d2_reflect_class.Student进程已结束,退出代码为 0
3.反射获取构造器对象
package com.wjh.d2_reflect_constructor;
public class Student {
private String name;
private int age;
public Student() {
System.out.println("无参构造器执行!");
}
private Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.wjh.d2_reflect_constructor;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestStudent1 {
// 1.Constructor<?>[] getConstructors()
// 返回所有构造器对象的数组(只能拿public的)
@Test
public void getConstructors(){
//a.第一步:获取类对象
Class c = Student.class;
//b.提取类中的全部构造器对象(只能拿public的)
Constructor[] constructors = c.getConstructors();
//c.遍历构造器
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
}
// 2.Constructor<?>[] getDeclaredConstructors()
// 返回所有构造器对象的数组,存在就能拿到
@Test
public void getDeclaredConstructors(){
//a.第一步:获取类对象
Class c = Student.class;
//b.提取类中的全部构造器对象(能拿全部的)
Constructor[] constructors = c.getDeclaredConstructors();
//c.遍历构造器
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
}
// 3.Constructor<T> getConstructor(Class<?>... parameterTypes)
// 返回单个构造器对象(只能拿public的)
@Test
public void getConstructor() throws NoSuchMethodException {
//a.第一步:获取类对象
Class c = Student.class;
//b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的)
Constructor constructor = c.getConstructor();
//c.遍历构造器
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
// 4.Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
// 返回单个构造器对象,存在就能拿到
@Test
public void getDeclaredConstructor() throws NoSuchMethodException {
//a.第一步:获取类对象
Class c = Student.class;
//b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的,能拿所有构造器)
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
//c.定位某个有参构造器
Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
}
}
package com.wjh.d2_reflect_constructor;
public class Student {
private String name;
private int age;
private Student() {
System.out.println("无参构造器执行!");
}
public Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.wjh.d2_reflect_constructor;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class TestStudent2 {
//1.调用无参构造器得到一个类的对象返回
@Test
public void getDeclaredConstructor() throws Exception {
//a.第一步:获取类对象
Class c = Student.class;
//b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的,能拿所有构造器)
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
//如果遇到私有的构造器,可以暴力反射
constructor.setAccessible(true); //权限被打开
Student s = (Student) constructor.newInstance();
System.out.println(s);
//c.定位某个有参构造器
Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
Student s1 = (Student) constructor1.newInstance("小黑子", 1000);
System.out.println(s1);
}
//2.调用有参构造器得到一个类的对象返回
}
4.反射获取成员变量对象
package com.wjh.d4_reflect_field;
public class Student {
private String name;
private int age;
public static String schoolName;
public static final String COUNT = "中国";
public Student() {
System.out.println("无参构造器执行!");
}
public Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.wjh.d4_reflect_field;
import org.junit.Test;
import java.lang.reflect.Field;
// Field[] getFields() 返回所有成员变量对象的数组(只能拿public的)
// Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到
// Field getField(String name) 返回单个成员变量对象(只能拿public的)
// Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到Field[] getFields() 返回所有成员变量对象的数组(只能拿public的)
// Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到
// Field getField(String name) 返回单个成员变量对象(只能拿public的)
// Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到
public class FieldDemo1 {
/*
1.获取全部的成员变量
Field[] getDeclareFields();
获取所有的成员变量对应的Field对象,只要申明了就可以得到
*/
@Test
public void getDeclareFields(){
//a.定位class对象
Class c = Student.class;
//b.定位全部成员变量
Field[] fields = c.getDeclaredFields();
//c.遍历一下
for (Field field : fields) {
System.out.println(field.getName() + "===>" + field.getType());
}
}
/*
2.获取某个成员变量对象
*/
@Test
public void getDeclaredField() throws NoSuchFieldException {
//a.定位class对象
Class c = Student.class;
//b.根据名称定位某个成员变量
Field f = c.getDeclaredField("age");
//c.遍历一下
System.out.println(f.getName() + "===>" + f.getType());
}
}
package com.wjh.d4_reflect_field;
import java.lang.reflect.Field;
import org.junit.Test;
public class FieldDemo2 {
@Test
public void getDeclareFields() throws Exception {
//a.定位class对象
Class c = Student.class;
//b.提取某个成员变量
Field ageF = c.getDeclaredField("age");
ageF.setAccessible(true);
//c.赋值
Student s = new Student();
ageF.set(s, 18);
System.out.println(s);
//d.取值
int age = (int) ageF.get(s);
System.out.println(age);
}
}
5.反射获取方法对象
package com.wjh.d5_reflect_method;
public class Dog {
private String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
public void run(){
System.out.println("狗跑得很快!");
}
public void eat(){
System.out.println("狗吃骨头");
}
private String eat(String name){
System.out.println("狗吃" + name);
return "吃得很开心";
}
public static void inAddress(){
System.out.println("在南工很多人学习Java");
}
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.wjh.d5_reflect_method;
import org.junit.Test;
import java.lang.reflect.Method;
public class MethodDemo01 {
/*
1.获得类中所有成员方法对象
*/
@Test
public void getDeclaredMethods(){
//a.获取类对象
Class c = Dog.class;
//b.提取全部方法,包括私有的
Method[] methods = c.getDeclaredMethods();
//c.遍历全部方法
for (Method method : methods) {
System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());
}
}
/*
2.获得某个方法对象
*/
@Test
public void getDeclaredMethod() throws Exception {
//a.获取类对象
Class c = Dog.class;
//b.提取单个方法对象
Method method = c.getDeclaredMethod("eat");
Method method2 = c.getDeclaredMethod("eat", String.class);
//c.
System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());
}
}
方法名:eat 返回值类型:void 参数个数:0
方法名:getName 返回值类型:class java.lang.String 参数个数:0
方法名:run 返回值类型:void 参数个数:0
方法名:toString 返回值类型:class java.lang.String 参数个数:0
方法名:setName 返回值类型:void 参数个数:1
方法名:eat 返回值类型:void 参数个数:0
方法名:eat 返回值类型:class java.lang.String 参数个数:1
方法名:inAddress 返回值类型:void 参数个数:0进程已结束,退出代码为 0
@Test
public void getDeclaredMethod() throws Exception {
//a.获取类对象
Class c = Dog.class;
//b.提取单个方法对象
Method method = c.getDeclaredMethod("eat");
Method method2 = c.getDeclaredMethod("eat", String.class);
System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());
method.setAccessible(true);
method2.setAccessible(true);
//c.触发方法的执行
Dog d = new Dog();
//注意:方法如果是没有结果回来的,那么返回的是null
Object result = method.invoke(d);
System.out.println(result); //null
method2.invoke(d, "骨头头");
Object result2 = method.invoke(d);
System.out.println(result2);
}
狗吃骨头头
狗吃骨头
null进程已结束,退出代码为 0
6.反射的作用-绕过编译阶段为集合添加数据
package com.wjh.d6_reflect_genericity;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//需求:反射实现泛型擦除后,加入其他类型的元素
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass()); //class java.util.ArrayList
System.out.println(list2.getClass()); //class java.util.ArrayList
System.out.println(list1.getClass() == list2.getClass()); //Class文件是否一样 -> true
System.out.println("==================================");
ArrayList<Integer> list3 = new ArrayList<>();
list3.add(23);
list3.add(24);
//list3.add("南工");
Class c = list3.getClass(); //ArrayList.class ==> public boolean add(E e){}
//定位c类中的add方法
Method add = c.getDeclaredMethod("add", Object.class);
boolean rs = (boolean) add.invoke(list3, "南工");
System.out.println(rs);
System.out.println(list3);
}
}
class java.util.ArrayList
class java.util.ArrayList
true
==================================
true
[23, 24, 南工]进程已结束,退出代码为 0
ArrayList list4 = list3;
list4.add("牛马");
list4.add(23);
list4.add(false);
System.out.println(list4); //[23, 24, 南工, 牛马, 23, false]
7.反射的作用-通用框架的底层原理
package com.wjh.d7_reflect_framework;
public class Student {
private String name;
private char sex;
private int age;
private String className;
private String hobby;
public Student() {
}
public Student(String name, char sex, int age, String className, String hobby) {
this.name = name;
this.sex = sex;
this.age = age;
this.className = className;
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
", className='" + className + '\'' +
", hobby='" + hobby + '\'' +
'}';
}
}
package com.wjh.d7_reflect_framework;
public class Teacher {
private String name;
private char sex;
private double salary;
public Teacher() {
}
public Teacher(String name, char sex, double salary) {
this.name = name;
this.sex = sex;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", sex=" + sex +
", salary=" + salary +
'}';
}
}
package com.wjh.d7_reflect_framework;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class MyBatisUtil {
/**
* 保存任意类型的对象
* @param obj
*/
public static void save(Object obj){
try(
PrintStream ps = new PrintStream(new FileOutputStream("D:\\JavaDemo\\JavaSEPro\\JavaSEProMax\\junit-reflect-annotation-app\\src\\date.txt",true));
) {
//1.提取这个对象的全部成员变量.只有反射可以解决
Class c = obj.getClass(); // (c.getSimpleName() 获取当前类名 c.getName获取全限名: 包名 + 类名)
ps.println("\n==========" + c.getSimpleName() + "=========");
//2.提取他的全部成员变量
Field[] fields = c.getDeclaredFields();
//3.获取成员变量的信息
for (Field field : fields) {
String name = field.getName();
//提取本成员变量在obj对象中的值(取值)
field.setAccessible(true);
String value = field.get(obj) + "";
ps.println(name + " = " + value);
}
//ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
==========Student=========
name = 猪八戒
sex = 男
age = 1000
className = 幼儿园大班
hobby = 吃饭,睡觉
==========Teacher=========
name = 波妞
sex = 女
salary = 30000.0
三.注解
1.注解概述
2.自定义注解
package com.wjh.d8_annotation;
/*
目标:学会自定义注解+,掌握其定义格式和语法
*/
@MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
public class AnnotationDemo1 {
@MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
private AnnotationDemo1(){
}
@MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
public static void main(String[] args) {
int age = 21;
}
}
package com.wjh.d8_annotation;
public @interface MyBook {
//public String name();
String name();
String[] authors();
double price();
}
package com.wjh.d8_annotation;
public @interface Book {
String value(); //特殊属性
double price() default 9.9;
}
//@Book(value = "/delete")
@Book(value = "/delete", price = 23.5)
//@Book("/delete")
private AnnotationDemo1(){
}
3.元注解
package com.wjh.d8_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD}) //元注解
@Retention(RetentionPolicy.RUNTIME) //一直活着,在运行阶段这个注解也不会消失
public @interface MyTest {
}
package com.wjh.d8_annotation;
/*
目标:认识元注解
*/
//@MyTest //只能注解申明过方法和成员变量
public class AnnotationDemo2 {
@MyTest
private String name;
@MyTest
public void test(){
}
public static void main(String[] args) {
}
}
4.注解解析
package com.wjh.d8_annotation;
/*
目标:完成注解的解析
*/
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationDemo3 {
@Test
public void parseMethod() throws Exception {
//a.先得到类对象
Class c = BookStore.class;
Method m = c.getDeclaredMethod("test");
//b.判断这个类上面是否存在这个注解
if(c.isAnnotationPresent(Bokk.class)){
//c.直接获取该注解对象
Bokk book =(Bokk)c.getDeclaredAnnotation(Bokk.class);
System.out.println(book.value());
System.out.println(book.price());
System.out.println(Arrays.toString(book.authors()));
}
}
}
@Bokk(value = "<<琅琊榜>>", price = 99.9, authors = {"苏哲", "蒙挚"})
class BookStore{
@Bokk(value = "<<jjj>>", price = 19.9, authors = {"www", "hhh"})
public void test(){
}
}
package com.wjh.d8_annotation;
public @interface Bokk {
//String name();
double price();
String[] authors();
String value();
}
5.注解的应用场景一:junit框架
package com.wjh.d8_annotation;
/*
目标:认识元注解
*/
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class AnnotationDemo4 {
@MyTest
public void test1(){
System.out.println("===test1===");
}
public void test2(){
System.out.println("===test2===");
}
@MyTest
public void test3(){
System.out.println("===test3===");
}
/**
* 启动菜单:有注解的才调用
* @param args
*/
public static void main(String[] args) throws Exception{
AnnotationDemo4 t = new AnnotationDemo4();
//a.获取类对象
Class c = AnnotationDemo4.class;
//b.提取全部方法
Method[] methods = c.getDeclaredMethods();
//c.遍历方法看是否有注解
for (Method method : methods) {
if(method.isAnnotationPresent(MyTest.class)){
//跑他
method.invoke(t);
}
}
}
}
===test1===
===test3===进程已结束,退出代码为 0
四.动态代理
1.动态代理概述,快速入门
package com.wjh.d9_proxy;
public class Star implements Skill{
private String name;
public Star() {
}
public Star(String name) {
this.name = name;
}
@Override
public void jump() {
System.out.println(name + "开始跳舞!!");
}
@Override
public void sing() {
System.out.println(name + "开始唱歌!!");
}
}
package com.wjh.d9_proxy;
/*
代理接口类
*/
public interface Skill {
void jump(); //跳舞
void sing(); //唱歌
}
package com.wjh.d9_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class StarAgentProxy {
/**
* 设计一个方法来返回一个明星对象的代理对象
*
*/
public static Skill getProxy(Star obj){
//为ycy这个对象,生成一个代理对象
/*
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,对象的实现接口列表
InvocationHandler h)
*/
return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("收首付款");
//真正的让ycy去唱歌和跳舞...
//method 正在调用的方法和对象 args 代表这个方法的参数
Object rs = method.invoke(obj, args);
System.out.println("收首付款,把ycy接回来!");
return rs;
}
});
}
}
package com.wjh.d9_proxy;
public class Test {
public static void main(String[] args) {
//目标:学习开发出一个代理对象出来,理解动态代理执行流程
//1.创建一个对象(ycy),对象的类必须实现接口
Star s = new Star("杨程宇");
//为ycy对象,生成一个代理对象(经纪人)
Skill s2 = StarAgentProxy.getProxy(s);
s2.jump(); //走代理的
s2.sing();
}
}
收首付款
杨程宇开始跳舞!!
收首付款,把ycy接回来!
收首付款
杨程宇开始唱歌!!
收首付款,把ycy接回来!进程已结束,退出代码为 0
2.动态代理的应用案例: 做性能分析,代理的好处小结
package com.wjh.d10_proxy2;
public interface UserService {
String login(String loginName, String passWord);
void deleteUser();
String selectUsers();
}
package com.wjh.d10_proxy2;
//实现类
public class UserServiceImpl implements UserService {
@Override
public String login(String loginName, String passWord) {
long startTime = System.currentTimeMillis();
String rs = "用户名或密码有误!";
if ("admin".equals(loginName) && "123456".equals(passWord)) {
rs = "登录成功!";
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("login方法耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}
@Override
public void deleteUser() {
long startTime = System.currentTimeMillis();
try {
System.out.println("正在删除数据...");
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("delete方法耗时:" + (endTime - startTime) / 1000.0 + "s");
}
@Override
public String selectUsers() {
long startTime = System.currentTimeMillis();
String rs = "查询了10000个用户";
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("select法耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}
}
package com.wjh.d10_proxy2;
public class Test {
public static void main(String[] args) {
//目标:掌握使用动态代理解决问题,理解使用动态代理的优势
UserService userService = new UserServiceImpl();
System.out.println(userService.login("admin", "123456"));
System.out.println(userService.selectUsers());
userService.deleteUser();
}
}
login方法法耗时:1.008s
登录成功!
selectUsers方法法耗时:3.015s
查询了10000个用户
正在删除数据...
deleteUser方法法耗时:2.002s进程已结束,退出代码为 0
问题:
package com.wjh.d10_proxy2;
public interface UserService {
String login(String loginName, String passWord);
void deleteUser();
String selectUsers();
void deleteById(int id);
}
package com.wjh.d10_proxy2;
//实现类
public class UserServiceImpl implements UserService {
@Override
public String login(String loginName, String passWord) {
String rs = "用户名或密码有误!";
if ("admin".equals(loginName) && "123456".equals(passWord)) {
rs = "登录成功!";
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
@Override
public void deleteUser() {
try {
System.out.println("正在删除数据...");
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String selectUsers() {
String rs = "查询了10000个用户";
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
@Override
public void deleteById(int id) {
try {
System.out.println("根据用户的身份证号:" + id + "删除了该账户");
Thread.sleep(1500);
}catch (Exception e){
e.printStackTrace();
}
}
}
package com.wjh.d10_proxy2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class proxyUtil {
/**
* 通过一个静态方法:为用户业务对象返回一个代理对象
*/
public static UserService getProxy(UserService obj){
return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
//真正触发对象行为执行的
Object rs = method.invoke(obj, args);
//System.out.println(rs);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法法耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}
});
}
}
package com.wjh.d10_proxy2;
public class Test {
public static void main(String[] args) {
//目标:掌握使用动态代理解决问题,理解使用动态代理的优势
UserService userService = proxyUtil.getProxy(new UserServiceImpl());
System.out.println(userService.login("admin", "123456"));
System.out.println(userService.selectUsers());
userService.deleteUser();
userService.deleteById(162152);
}
}
login方法法耗时:1.003s
登录成功!
selectUsers方法法耗时:3.003s
查询了10000个用户
正在删除数据...
deleteUser方法法耗时:2.004s
根据用户的身份证号:162152删除了该账户
deleteById方法法耗时:1.509s进程已结束,退出代码为 0
package com.wjh.d10_proxy2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class proxyUtil {
/**
* 通过一个静态方法:为用户业务对象返回一个代理对象
*/
public static <T> T getProxy(T obj){
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
//真正触发对象行为执行的
Object rs = method.invoke(obj, args);
//System.out.println(rs);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法法耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}
});
}
}
为任意接口的实现类对象做代理