自定义注解
1.1 案例一:使用自定义注解模拟@Test注解功能
1.1.1 需求
使用Junit是单元测试的工具.在一个类中使用 @Test 对程序中的方法进行测试.
自定义一个注解@MyTest 也将这个注解加在类的方法上. 使这个方法得到执行.
1.1.2 分析:
1.1.2.1 技术分析:
Ø 【注解】
程序中有 注释 和注解
-
注释:给开发人员. // /* / /* */
-
注解:给计算机看的. @Override
注解使用:学习框架支持注解开发. 注解可以简化xml(可以省略xml文件)
Ø 【JDK提供的三个基本的注解】
@Override :描述方法的重写.
@SuppressWarnings :压制警告.
@Deprecated :标记过时.
自定义注解:(肉体)
定义一个类:class
定义一个接口:interface
定义一个枚举:enum
定义一个注解:@interface
【自定义注解案例】
@interface MyAnno1{
}
分析注解中的成员
属性 : 例:int age();
关于注解的属性类型可以有哪些?
1.基本类型
2.String
3.枚举类型
4.注解类型
5.Class类型
6.以上类型的一维数组类型
带有属性的注解:
定义核心运行类:
在核心运行类中有一个主函数:
获得测试类中的所有的方法.
获得每个方法,查看方法上是否有@MyTest注解.
如果有这个注解,让这个方法执行.
【注解的反射】(灵魂)
模拟Junit的@Test
a、反射注解类
java.lang.reflect.AnnotatedElement:
l T getAnnotation(Class annotationType):得到指定类型的注解引用。没有返回null。
l Annotation[] getAnnotations():得到所有的注解,包含从父类继承下来的。
l Annotation[] getDeclaredAnnotations():得到自己身上的注解。
l boolean isAnnotationPreent(Class<? extends Annotation> annotationType):判断指定的注解有没有。
Class、Method、Field、Constructor等实现了AnnotatedElement接口.
如果:Class.isAnnotationPresent(MyTest.class):判断类上面有没有@MyTest注解;
Method.isAnnotationPresent(MyTest.class):判断方法上面有没有@MyTest注解。
1.1.3 代码实现:
【元注解】
a、自定义的注解的存活范围(生命周期):默认是CLASS。
什么是元注解:
只能用在注解上的注解叫做元注解。(即:用于修饰注解的注解)
l @Retention:作用。改变自定义的注解的存活范围。
RetentionPolicy:
SOURCE
CLASS
RUNTIME
l @Target:作用,指定该注解能用在什么地方。
ElementType:
TYPE:类、接口、枚举
METHOD:方法
FIELD:字段
ANNOTATION_TYPE:注解
1.2 案例二:使用动态代理解决用户转账的事务管理
1.2.1 需求:
Ø使用动态代理解决用户转账的事务管理。
1.2.2 分析:
1.2.2.1 技术分析:
【动态代理】
意义:增强一个类中的某个方法.对程序进行扩展.Spring框架中AOP.
什么是代理:
Proxy Pattern(即:代理模式),23种常用的面向对象软件的设计模式之一
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
动态代理:
动态代理它可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在。
动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。
动态代理生成技术:
1.jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象。
2.cglib (spring学习)
ava.lang.reflect.Proxy类可以直接生成一个代理对象
Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。
Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。
InvocationHandler:策略(方案)设计模式的应用。代理对象如何调用真实对象的方法。
InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行
Object proxy:代理对象本身的引用。一般用不着。
Method method:当前调用的方法。m.invoke(p,null);
Object[] args:当前方法用到的参数
使用动态代理执行转账事务控制:
1、DAO中参与事务的方法要使用同一个Connection
2、业务类要实现接口
3、编写动态代理工厂
4、在servlet中使用代理对象,调用方法
【AOP编程思想】 (面向切面编程)
1、问题:业务方法日后会很多,会有很多重复的代码
2、问题:已经存在很多的方法,并没有考虑到事务的问题,现在要求加上。
【入门案例】
1.2.3 代码实现:
代码参见:
1.2.4.1 【类的加载器:了解】
【类加载器 ClassLoader】
1、作用:类加载器就是将.class文件加载到内存生成Class对象.
2、JVM中的类加载器:
BootStrap: 引导类加载器 老大。类加载器的祖先。
负责加载JRE/lib/rt.jar ( 加载JDK中绝大部分的类) runtime
ExtClassLoader:扩展类加载器
负责加载JRE/lib/ext/*.jar
AppClassLoader:应用类加载器
负责加载在classpath环境变量中的所有类。
3、父类委托机制
class A{
String s;
}
class文件由应用类加载器获得到,没有加载,向上一层委托向扩展类加载器委托,向上一层进行委托委托给引导类加载器.引导类加载器查看class哪些它负责,将自己负责的这个class进行加载.不是其负责的就向下传递扩展类加载器.扩展类加载器查看是否是其管理的class,如果是加载,不是就再向下到应用类加载器.