当前位置: 首页 > news >正文

白云区手机版网站建设公司标志图片logo

白云区手机版网站建设,公司标志图片logo,安庆做网站哪个公司好,cms仿站教程目录 单元测试 单元测试概述 单元测试快速入门 单元测试常用注解 反射 反射概述 反射获取类对象 反射获取构造器对象 反射获取成员变量对象 反射获取方法对象 反射的作用-绕过编译阶段为集合添加数据 反射的作用-通用框架的底层原理 注解 注解概述 自定义注解 …目录 单元测试 单元测试概述 单元测试快速入门 单元测试常用注解 反射 反射概述 反射获取类对象 反射获取构造器对象 反射获取成员变量对象 反射获取方法对象 反射的作用-绕过编译阶段为集合添加数据 反射的作用-通用框架的底层原理 注解 注解概述 自定义注解 元注解 注解解析 注解的应用场景一junit框架 动态代理 准备案例、提出问题 使用动态代理解决问题 单元测试 单元测试概述 单元测试单元测试就是针对最小的功能单元编写测试代码Java程序最小的功能单元是方法因此单元测试就是针对Java方法的测试进而检查方法的正确性。 目前测试方法是怎么进行的存在什么问题只有一个main方法如果一个方法的测试失败了其他方法测试会受到影响。无法得到测试的结果报告需要程序员自己去观察测试是否成功。无法实现自动化测试。 Junit单元测试框架 JUnit是使用Java语言实现的单元测试框架它是开源的Java开发者都应当学习并使用JUnit编写单元测试。 此外几乎所有的IDE工具都集成了JUnit这样我们就可以直接在IDE中编写并运行JUnit测试JUnit目前最新版本是5。 JUnit优点JUnit可以灵活的选择执行哪些测试方法可以一键执行全部测试方法。Junit可以生成全部方法的测试报告。单元测试中的某个方法测试失败了不会影响其他测试方法的测试。 总结 Junit单元测试是做什么的测试类中方法的正确性的。 Junit单元测试的优点是什么JUnit可以选择执行哪些测试方法可以一键执行全部测试方法的测试。JUnit可以生测试报告如果测试良好则是绿色如果测试失败则是红色。单元测试中的某个方法测试失败了不会影响其他测试方法的测试。单元测试快速入门 单元测试快速入门 需求使用单元测试进行业务方法预期结果、正确性测试的快速入门 分析将JUnit的jar包导入到项目中IDEA通常整合好了Junit框架一般不需要导入。如果IDEA没有整合好需要自己手工导入如下2个JUnit的jar包到模块编写测试方法该测试方法必须是公共的无参数无返回值的非静态方法。在测试方法上使用Test注解标注该方法是一个测试方法在测试方法中完成被测试方法的预期正确性测试。选中测试方法选择“JUnit运行” 如果测试良好则是绿色如果测试失败则是红色 /**业务方法*/ public class UserService {public String loginName(String loginName , String passWord){if(admin.equals(loginName) 123456.equals(passWord)){return 登录成功;}else {return 用户名或者密码有问题;}}public void selectNames(){System.out.println(10/2);System.out.println(查询全部用户名称成功~~);} }import org.junit.*;/**测试类*/ public class TestUserService {// 修饰实例方法的Beforepublic void before(){System.out.println(before方法执行一次);}Afterpublic void after(){System.out.println(after方法执行一次);}// 修饰静态方法BeforeClasspublic static void beforeClass(){System.out.println(beforeClass方法执行一次);}AfterClasspublic static void afterClass(){System.out.println(afterClass方法执行一次);}/**测试方法注意点1、必须是公开的无参数 无返回值的方法2、测试方法必须使用Test注解标记。*/Testpublic void testLoginName(){UserService userService new UserService();String rs userService.loginName(admin,123456);// 进行预期结果的正确性测试断言。Assert.assertEquals(您的登录业务可能出现问题, 登录成功, rs );}Testpublic void testSelectNames(){UserService userService new UserService();userService.selectNames();} } 单元测试常用注解 Junit常用注解(Junit 4.xxxx版本) 注解 说明 Test 测试方法 Before 用来修饰实例方法该方法会在每一个测试方法执行之前执行一次。 After 用来修饰实例方法该方法会在每一个测试方法执行之后执行一次。 BeforeClass 用来静态修饰方法该方法会在所有测试方法之前只执行一次。 AfterClass 用来静态修饰方法该方法会在所有测试方法之后只执行一次。 开始执行的方法:初始化资源。 执行完之后的方法:释放资源。 反射 反射概述 反射概述反射是指对于任何一个Class类在运行的时候都可以直接得到这个类全部成分。在运行时,可以直接得到这个类的构造器对象Constructor在运行时,可以直接得到这个类的成员变量对象Field在运行时,可以直接得到这个类的成员方法对象Method这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。 反射的关键反射的第一步都是先得到编译后的Class类对象然后就可以得到Class的全部成分。反射获取类对象 反射的第一步获取Class类的对象 package com.deng.hello;public class Student { }package com.deng.hello;/**目标反射的第一步获取Class对象*/ public class Test {public static void main(String[] args) throws Exception {// 1、Class类中的一个静态方法forName(全限名包名 类名)Class c Class.forName(package com.deng.hello.Student);System.out.println(c); // Student.class// 2、类名.classClass c1 Student.class;System.out.println(c1);// 3、对象.getClass() 获取对象对应类的Class对象。Student s new Student();Class c2 s.getClass();System.out.println(c2);} } 总结 反射的第一步是什么获取Class类对象如此才可以解析类的全部成分 获取Class类的对象的三种方式方式一Class c1 Class.forName(“全类名”);方式二Class c2 类名.class方式三Class c3 对象.getClass();反射获取构造器对象 使用反射技术获取构造器对象并使用 反射的第一步是先得到类对象然后从类对象中获取类的成分对象。 Class类中用于获取构造器的方法方法 说明 Constructor?[] getConstructors​() 返回所有构造器对象的数组只能拿public的 Constructor?[] getDeclaredConstructors​() 返回所有构造器对象的数组存在就能拿到 ConstructorT getConstructor​(Class?... parameterTypes) 返回单个构造器对象只能拿public的 ConstructorT getDeclaredConstructor​(Class?... parameterTypes) 返回单个构造器对象存在就能拿到 获取构造器的作用依然是初始化一个对象返回。Constructor类中用于创建对象的方法 符号 说明 T newInstance​(Object... initargs) 根据指定的构造器创建对象 public void  setAccessible(boolean flag) 设置为true,表示取消访问检查进行暴力反射 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;}Overridepublic String toString() {return Student{ name name \ , age age };} }import org.junit.Test;import java.lang.reflect.Constructor;/**目标反射_获取Constructor构造器对象.反射的第一步是先得到Class类对象。Class文件反射中Class类型获取构造器提供了很多的API:1. Constructor getConstructor(Class... parameterTypes)根据参数匹配获取某个构造器只能拿public修饰的构造器几乎不用2. Constructor getDeclaredConstructor(Class... parameterTypes)根据参数匹配获取某个构造器只要申明就可以定位不关心权限修饰符建议使用3. Constructor[] getConstructors()获取所有的构造器只能拿public修饰的构造器。几乎不用太弱了4. Constructor[] getDeclaredConstructors()获取所有申明的构造器只要你写我就能拿到无所谓权限。建议使用小结获取类的全部构造器对象 Constructor[] getDeclaredConstructors()-- 获取所有申明的构造器只要你写我就能拿到无所谓权限。建议使用获取类的某个构造器对象Constructor getDeclaredConstructor(Class... parameterTypes)-- 根据参数匹配获取某个构造器只要申明就可以定位不关心权限修饰符建议使用*/ public class TestStudent01 {// 1. getConstructors:// 获取全部的构造器只能获取public修饰的构造器。// Constructor[] getConstructors()Testpublic 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.getDeclaredConstructors():// 获取全部的构造器只要你敢写这里就能拿到无所谓权限是否可及。Testpublic 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.getConstructor(Class... parameterTypes)// 获取某个构造器只能拿public修饰的某个构造器Testpublic void getConstructor() throws Exception {// a.第一步获取类对象Class c Student.class;// b.定位单个构造器对象 (按照参数定位无参数构造器 只能拿public修饰的某个构造器)Constructor cons c.getConstructor();System.out.println(cons.getName() cons.getParameterCount());}// 4.getConstructor(Class... parameterTypes)// 获取某个构造器只要你敢写这里就能拿到无所谓权限是否可及。Testpublic void getDeclaredConstructor() throws Exception {// a.第一步获取类对象Class c Student.class;// b.定位单个构造器对象 (按照参数定位无参数构造器)Constructor cons c.getDeclaredConstructor();System.out.println(cons.getName() cons.getParameterCount());// c.定位某个有参构造器Constructor cons1 c.getDeclaredConstructor(String.class, int.class);System.out.println(cons1.getName() cons1.getParameterCount());} } import org.junit.Test;import java.lang.reflect.Constructor;/**目标: 反射_获取Constructor构造器然后通过这个构造器初始化对象。反射获取Class中的构造器对象Constructor作用也是初始化并得到类的一个对象返回。Constructor的API:1. T newInstance(Object... initargs)创建对象注入构造器需要的数据。2. void setAccessible(true)修改访问权限true代表暴力攻破权限false表示保留不可访问权限(暴力反射)小结可以通过定位类的构造器对象。如果构造器对象没有访问权限可以通过void setAccessible(true)打开权限构造器可以通过T newInstance(Object... initargs)调用自己传入参数*/ public class TestStudent02 {// 1.调用构造器得到一个类的对象返回。Testpublic void getDeclaredConstructor() throws Exception {// a.第一步获取类对象Class c Student.class;// b.定位单个构造器对象 (按照参数定位无参数构造器)Constructor cons c.getDeclaredConstructor();System.out.println(cons.getName() cons.getParameterCount());// 如果遇到了私有的构造器可以暴力反射cons.setAccessible(true); // 权限被打开Student s (Student) cons.newInstance();System.out.println(s);System.out.println(-------------------);// c.定位某个有参构造器Constructor cons1 c.getDeclaredConstructor(String.class, int.class);System.out.println(cons1.getName() cons1.getParameterCount());Student s1 (Student) cons1.newInstance(孙悟空, 1000);System.out.println(s1);} } 总结 利用反射技术获取构造器对象的方式getDeclaredConstructors()getDeclaredConstructor (Class?... parameterTypes) 反射得到的构造器可以做什么依然是创建对象的public newInstance(Object... initargs) 如果是非public的构造器需要打开权限暴力反射然后再创建对象setAccessible(boolean)反射可以破坏封装性私有的也可以执行了。 反射获取成员变量对象 使用反射技术获取成员变量对象并使用 反射的第一步是先得到类对象然后从类对象中获取类的成分对象。 Class类中用于获取成员变量的方法 方法 说明 Field[] getFields​() 返回所有成员变量对象的数组只能拿public的 Field[] getDeclaredFields​() 返回所有成员变量对象的数组存在就能拿到 Field getField​(String name) 返回单个成员变量对象只能拿public的 Field getDeclaredField​(String name) 返回单个成员变量对象存在就能拿到 获取成员变量的作用依然是在某个对象中取值、赋值Field类中用于取值、赋值的方法 符号 说明 void set​(Object obj, Object value) 赋值 Object get​(Object obj) 获取值。 public class Student {private String name;private int age;public static String schoolName;public static final String COUNTTRY 中国;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;}Overridepublic String toString() {return Student{ name name \ , age age };} }import org.junit.Test;import java.io.File; import java.lang.reflect.Field;/**目标反射_获取Field成员变量对象。反射的第一步是先得到Class类对象。1、Field getField(String name);根据成员变量名获得对应Field对象只能获得public修饰2.Field getDeclaredField(String name);根据成员变量名获得对应Field对象只要申明了就可以得到3.Field[] getFields();获得所有的成员变量对应的Field对象只能获得public的4.Field[] getDeclaredFields();获得所有的成员变量对应的Field对象只要申明了就可以得到小结获取全部成员变量getDeclaredFields获取某个成员变量getDeclaredField*/ public class FieldDemo01 {/*** 1.获取全部的成员变量。* Field[] getDeclaredFields();* 获得所有的成员变量对应的Field对象只要申明了就可以得到*/Testpublic void getDeclaredFields(){// a.定位Class对象Class c Student.class;// b.定位全部成员变量Field[] fields c.getDeclaredFields();// c.遍历一下for (Field field : fields) {System.out.println(field.getName() field.getType());}}/**2.获取某个成员变量对象 Field getDeclaredField(String name);*/Testpublic void getDeclaredField() throws Exception {// a.定位Class对象Class c Student.class;// b.根据名称定位某个成员变量Field f c.getDeclaredField(age);System.out.println(f.getName() f.getType());}} import org.junit.Test;import java.lang.reflect.Field;/**目标反射获取成员变量: 取值和赋值。Field的方法给成员变量赋值和取值void set(Object obj, Object value)给对象注入某个成员变量数据Object get(Object obj):获取对象的成员变量的值。void setAccessible(true);暴力反射设置为可以直接访问私有类型的属性。Class getType(); 获取属性的类型返回Class对象。String getName(); 获取属性的名称。*/ public class FieldDemo02 {Testpublic void setField() throws Exception {// a.反射第一步获取类对象Class c Student.class;// b.提取某个成员变量Field ageF c.getDeclaredField(age);ageF.setAccessible(true); // 暴力打开权限// c.赋值Student s new Student();ageF.set(s , 18); // s.setAge(18);System.out.println(s);// d、取值int age (int) ageF.get(s);System.out.println(age);} }总结 利用反射技术获取成员变量的方式 获取类中成员变量对象的方法 getDeclaredFields() getDeclaredField (String name) 反射得到成员变量可以做什么 依然是在某个对象中取值和赋值。 void set​(Object obj, Object value) Object get​(Object obj) 如果某成员变量是非public的需要打开权限暴力反射然后再取值、赋值 setAccessible(boolean) 反射获取方法对象 使用反射技术获取方法对象并使用 反射的第一步是先得到类对象然后从类对象中获取类的成分对象。 Class类中用于获取成员方法的方法方法 说明 Method[] getMethods​() 返回所有成员方法对象的数组只能拿public的 Method[] getDeclaredMethods​() 返回所有成员方法对象的数组存在就能拿到 Method getMethod​(String name, Class?... parameterTypes) 返回单个成员方法对象只能拿public的 Method getDeclaredMethod​(String name, Class?... parameterTypes) 返回单个成员方法对象存在就能拿到 获取成员方法的作用依然是在某个对象中进行执行此方法Method类中用于触发执行的方法 符号 说明 Object invoke​(Object obj, Object... args) 运行方法 参数一用obj对象调用该方法 参数二调用方法的传递的参数如果没有就不写 返回值方法的返回值如果没有就不写 public class Dog {private String name ;public Dog(){}public Dog(String name) {this.name name;}public void run(){System.out.println(狗跑的贼快~~);}private void eat(){System.out.println(狗吃骨头);}private String eat(String name){System.out.println(狗吃 name);return 吃的很开心;}public static void inAddr(){System.out.println(在黑马学习Java!);}public String getName() {return name;}public void setName(String name) {this.name name;}} import org.junit.Test;import java.lang.reflect.Method;/**目标反射——获取Method方法对象反射获取类的Method方法对象1、Method getMethod(String name,Class...args);根据方法名和参数类型获得对应的方法对象只能获得public的2、Method getDeclaredMethod(String name,Class...args);根据方法名和参数类型获得对应的方法对象包括private的3、Method[] getMethods();获得类中的所有成员方法对象返回数组只能获得public修饰的且包含父类的4、Method[] getDeclaredMethods();获得类中的所有成员方法对象返回数组,只获得本类申明的方法。Method的方法执行Object invoke(Object obj, Object... args)参数一触发的是哪个对象的方法执行。参数二 args调用方法时传递的实际参数*/ public class MethodDemo01 {/*** 1.获得类中的所有成员方法对象*/Testpublic 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. 获取某个方法对象*/Testpublic void getDeclardMethod() throws Exception {// a.获取类对象Class c Dog.class;// b.提取单个方法对象Method m c.getDeclaredMethod(eat);Method m2 c.getDeclaredMethod(eat, String.class);// 暴力打开权限了m.setAccessible(true);m2.setAccessible(true);// c.触发方法的执行Dog d new Dog();// 注意方法如果是没有结果回来的那么返回的是null.Object result m.invoke(d);System.out.println(result);Object result2 m2.invoke(d, 骨头);System.out.println(result2);} } 总结 1、利用反射技术获取成员方法对象的方式获取类中成员方法对象getDeclaredMethods()getDeclaredMethod (String name, Class?... parameterTypes) 2、反射得到成员方法可以做什么依然是在某个对象中触发该方法执行。Object invoke​(Object obj, Object... args)如果某成员方法是非public的需要打开权限暴力反射然后再触发执行setAccessible(boolean) 反射的作用-绕过编译阶段为集合添加数据 反射的作用-绕过编译阶段为集合添加数据反射是作用在运行时的技术此时集合的泛型将不能产生约束了此时是可以为集合存入其他任意类型的元素的。 泛型只是在编译阶段可以约束集合只能操作某种数据类型 在编译成Class文件进入运行阶段的时候其真实类型都是ArrayList了 泛型相当于被擦除了。import java.lang.reflect.Method; import java.util.ArrayList;public class ReflectDemo {public static void main(String[] args) throws Exception {// 需求反射实现泛型擦除后加入其他类型的元素ArrayListString lists1 new ArrayList();ArrayListInteger lists2 new ArrayList();System.out.println(lists1.getClass());System.out.println(lists2.getClass());System.out.println(lists1.getClass() lists2.getClass()); // ArrayList.classSystem.out.println(---------------------------);ArrayListInteger lists3 new ArrayList();lists3.add(23);lists3.add(22);// lists3.add(Java);Class c lists3.getClass(); // ArrayList.class public boolean add(E e)// 定位c类中的add方法Method add c.getDeclaredMethod(add, Object.class);boolean rs (boolean) add.invoke(lists3, Java);System.out.println(rs);System.out.println(lists3);ArrayList list4 lists3;list4.add(MySQL);list4.add(false);System.out.println(lists3);} } 反射的作用-通用框架的底层原理 案例 反射做通用框架 需求 给你任意一个对象在不清楚对象字段的情况可以可以把对象的字段名称和对应值存储到文件中去。 分析 定义一个方法可以接收任意类的对象。 每次收到一个对象后需要解析这个对象的全部成员变量名称。 这个对象可能是任意的那么怎么样才可以知道这个对象的全部成员变量名称呢 使用反射获取对象的Class类对象然后获取全部成员变量信息。 遍历成员变量信息然后提取本成员变量在对象中的具体值 存入成员变量名称和值到文件中去即可。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;} } 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;} } 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(junit-reflect-annotation-proxy-app/src/data.txt, true));){// 1、提取这个对象的全部成员变量只有反射可以解决Class c obj.getClass(); // c.getSimpleName()获取当前类名 c.getName获取全限名包名类名ps.println( 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);}} catch (Exception e) {e.printStackTrace();}} } import java.util.Date; import java.util.Properties;/**目标提供一个通用框架支持保存所有对象的具体信息。*/ public class ReflectDemo {public static void main(String[] args) throws Exception {Student s new Student();s.setName(猪八戒);s.setClassName(西天跑路1班);s.setAge(1000);s.setHobby(吃睡);s.setSex(男);MybatisUtil.save(s);Teacher t new Teacher();t.setName(波仔);t.setSex(男);t.setSalary(6000);MybatisUtil.save(t);} } 总结 反射的作用 可以在运行时得到一个类的全部成分然后操作。 可以破坏封装性。很突出 也可以破坏泛型的约束性。很突出 更重要的用途是适合做Java高级框架 基本上主流框架都会基于反射设计一些通用技术功能。 注解 注解概述 注解的概述、作用 Java 注解Annotation又称 Java 标注是 JDK5.0 引入的一种注释机制。 Java 语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注。 作用对Java中类、方法、成员变量做标记然后进行特殊处理至于到底做何种处理由业务需求来决定。例如JUnit框架中标记了注解Test的方法就可以被当成测试方法执行而没有标记的就不能当成测试方法执行。自定义注解 自定义注解 --- 格式 自定义注解就是自己做一个注解来使用。 public interface MyBook {String name();String[] authors();double price(); } /**目标学会自定义注解。掌握其定义格式和语法。*/ MyBook(name《精通JavaSE》,authors {Java, dlei} , price 199.5) //Book(value /delete) // Book(/delete) Book(value /delete, price 23.5) //Book(/delete) public class AnnotationDemo1 {MyBook(name《精通JavaSE2》,authors {Java, dlei} , price 199.5)private AnnotationDemo1(){}MyBook(name《精通JavaSE1》,authors {Java, dlei} , price 199.5)public static void main(String[] args) {MyBook(name《精通JavaSE2》,authors {Java, dlei} , price 199.5)int age 21;} } 特殊属性 value属性如果只有一个value属性的情况下使用value属性的时候可以省略value名称不写!! 但是如果有多个属性, 且多个属性没有默认值那么value名称是不能省略的。 public interface Book {String value(); // 特殊属性double price() ;//double price() default 9.9; }元注解 元注解就是注解注解的注解。 元注解有两个Target: 约束自定义注解只能在哪些地方使用Retention申明注解的生命周期 Target中可使用的值定义在ElementType枚举类中常用值如下TYPE类接口FIELD, 成员变量METHOD, 成员方法PARAMETER, 方法参数CONSTRUCTOR, 构造器LOCAL_VARIABLE, 局部变量 Retention中可使用的值定义在RetentionPolicy枚举类中常用值如下SOURCE 注解只作用在源码阶段生成的字节码文件中不存在CLASS 注解作用在源码阶段字节码文件阶段运行阶段不存在默认值.RUNTIME注解作用在源码阶段字节码文件阶段运行阶段开发常用 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 { } /**目标认识元注解*/ //MyTest // 只能注解方法和成员变量 public class AnnotationDemo2 {MyTestprivate String name;MyTestpublic void test(){}public static void main(String[] args) {} }注解解析 注解的解析注解的操作中经常需要进行解析注解的解析就是判断是否存在注解存在注解就解析出内容。 与注解解析相关的接口Annotation: 注解的顶级接口注解都是Annotation类型的对象AnnotatedElement:该接口定义了与注解解析相关的解析方法 方法 说明 Annotation[]    getDeclaredAnnotations() 获得当前对象上使用的所有注解返回注解数组。 T getDeclaredAnnotation(ClassT annotationClass) 根据注解类型获得对应注解对象 boolean isAnnotationPresent(ClassAnnotation annotationClass) 判断当前对象是否使用了指定的注解如果使用了则返回true否则false 所有的类成分Class, Method , Field , Constructor 都实现了AnnotatedElement接口他们都拥有解析注解的能力解析注解的技巧 注解在哪个成分上我们就先拿哪个成分对象。比如注解作用成员方法则要获得该成员方法对应的Method对象再来拿上面的注解比如注解作用在类上则要该类的Class对象再来拿上面的注解比如注解作用在成员变量上则要获得该成员变量对应的Field对象再来拿上面的注解需求注解解析的案例 分析 定义注解Book要求如下- 包含属性String value() 书名- 包含属性double price() 价格默认值为 100- 包含属性String[] authors() 多位作者- 限制注解使用的位置类和成员方法上- 指定注解的有效范围RUNTIME 定义BookStore类在类和成员方法上使用Book注解 定义AnnotationDemo01测试类获取Book注解上的数据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 Bookk {String value();double price() default 100;String[] author(); }import org.junit.Test;import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays;/**目标完成注解的解析*/ public class AnnotationDemo3 {Testpublic void parseClass(){// a.先得到类对象Class c BookStore.class;// b.判断这个类上面是否存在这个注解if(c.isAnnotationPresent(Bookk.class)){//c.直接获取该注解对象Bookk book (Bookk) c.getDeclaredAnnotation(Bookk.class);System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.author()));}}Testpublic void parseMethod() throws NoSuchMethodException {// a.先得到类对象Class c BookStore.class;Method m c.getDeclaredMethod(test);// b.判断这个类上面是否存在这个注解if(m.isAnnotationPresent(Bookk.class)){//c.直接获取该注解对象Bookk book (Bookk) m.getDeclaredAnnotation(Bookk.class);System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.author()));}} }Bookk(value 《情深深雨濛濛》, price 99.9, author {琼瑶, dlei}) class BookStore{Bookk(value 《三少爷的剑》, price 399.9, author {古龙, 熊耀华})public void test(){} } 注解的应用场景一junit框架 模拟Junit框架 需求 定义若干个方法只要加了MyTest注解就可以在启动时被触发执行 分析 定义一个自定义注解MyTest只能注解方法存活范围是一直都在。 定义若干个方法只要有MyTest注解的方法就能在启动时被触发执行没有这个注解的方法不能执行。动态代理 准备案例、提出问题 模拟企业业务功能开发并完成每个功能的性能统计 需求 模拟某企业用户管理业务需包含用户登录用户删除用户查询功能并要统计每个功能的耗时。 分析 定义一个UserService表示用户业务接口规定必须完成用户登录用户删除用户查询功能。 定义一个实现类UserServiceImpl实现UserService并完成相关功能且统计每个功能的耗时。 定义测试类创建实现类对象调用方法。/**模拟用户业务功能*/ public interface UserService {String login(String loginName , String passWord) ;void selectUsers();boolean deleteUsers();void updateUsers(); }public class Test {public static void main(String[] args) {// 1、把业务对象直接做成一个代理对象返回代理对象的类型也是 UserService类型UserService userService ProxyUtil.getProxy(new UserServiceImpl());System.out.println(userService.login(admin, 1234));System.out.println(userService.deleteUsers());userService.selectUsers();userService.updateUsers(); // 走代理} } public class UserServiceImpl implements UserService{Overridepublic String login(String loginName, String passWord) {try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}if(admin.equals(loginName) 1234.equals(passWord)) {return success;}return 登录名和密码可能有毛病;}Overridepublic void selectUsers() {System.out.println(查询了100个用户数据);try {Thread.sleep(2000);} catch (Exception e) {e.printStackTrace();}}Overridepublic boolean deleteUsers() {try {System.out.println(删除100个用户数据);Thread.sleep(500);return true;} catch (Exception e) {e.printStackTrace();return false;}}Overridepublic void updateUsers() {try {System.out.println(修改100个用户数据);Thread.sleep(2500);} catch (Exception e) {e.printStackTrace();}} }本案例存在什么问题 答业务对象的的每个方法都要进行性能统计存在大量重复的代码。使用动态代理解决问题 动态代理代理就是被代理者没有能力或者不愿意去完成某件事情需要找个人代替自己去完成这件事动态代理就是用来对业务功能方法进行代理的。 关键步骤1.必须有接口实现类要实现接口代理通常是基于接口实现的。2.创建一个实现类的对象该对象为业务对象紧接着为业务对象做一个代理对象。 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /**public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)参数一类加载器负责加载代理类到内存中使用。参数二获取被代理对象实现的全部接口。代理要为全部接口的全部方法进行代理参数三代理的核心处理逻辑*/ public class ProxyUtil {/**生成业务对象的代理对象。* param obj* return*/public static T T getProxy(T obj) {// 返回了一个代理对象了return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 参数一代理对象本身。一般不管// 参数二正在被代理的方法// 参数三被代理方法应该传入的参数long startTimer System .currentTimeMillis();// 马上触发方法的真正执行。(触发真正的业务功能)Object result method.invoke(obj, args);long endTimer System.currentTimeMillis();System.out.println(method.getName() 方法耗时 (endTimer - startTimer) / 1000.0 s);// 把业务功能方法执行的结果返回给调用者return result;}});} } 动态代理的优点非常的灵活支持任意接口类型的实现类对象做代理也可以直接为接本身做代理。可以为被代理对象的所有方法做代理。可以在不改变方法源码的情况下实现对方法功能的增强。不仅简化了编程工作、提高了软件系统的可扩展性同时也提高了开发效率。
http://www.ho-use.cn/article/10823401.html

相关文章:

  • 想建个图片网站网站如何防止黑客攻击
  • 中铁建设集团有限公司官方网站网站网站二维码收钱怎么做的
  • 网站案例介绍确定网站的主题与风格
  • 做文章网站旗县长安网站建设思路
  • 沈阳做网站直播的公司网站设计师联盟
  • 东莞长安做网站公司自媒体营销代理
  • 包年seo和整站优化苏州做网站建设公司
  • 企业做网站的多吗修改文章缩略字数 WORDPRESS
  • 一站式wordpress 广告 统计
  • 自学网站有哪些wordpress token
  • 360建站模板低价网站建设案例
  • 做网站 新域名 还是皮肤科在线医生免费咨询
  • 写作投稿网站网上提供免费主页空间的网站
  • python一句做网站做网站几个步骤
  • 商城网站建设解决方案二级网站内容建设要求
  • 商务网站开发流程有三个阶段谷歌浏览器手机版
  • 北京的p2p网站建设深圳龙岗做网站的公司
  • 杭州住房城乡建设网站查询我想来做外贸网站来推广
  • 麒麟区住房和城乡建设局网站设计公司和装修公司的区别
  • 非凡网站建设搜索引擎是如何判断网站的结构
  • 网站建设行业分析装修网络公司
  • 城乡建设杂志社官方网站国外免费域名申请
  • 做淘宝客网站用什么系统吗淮北论坛最新招聘
  • 在印度做外贸需要什么网站辅助购卡网站怎么做
  • 自主网站怎么投诉网站制作公司
  • 网站制作怎么自己做国家职业资格证书网站
  • 国外网站网站app北京市建设工程安全质量监督总站网站
  • 网站建设上线问题网站做的简单是什么意思
  • 如何制作新型网站程序公司注册代理机构
  • 做pc网站会连带手机版如何制作短视频