( 反射 )Annotation 注解
@Test
public void testAnnotation() throws Exception{
String className = "com.reflectiondemo.Person";
Class classTemp = Class.forName(className);
Object obj = classTemp.newInstance();
Method method = classTemp.getDeclaredMethod("setAge", int.class);
int age = 17;
Annotation annotation = method.getAnnotation(AgeValidator.class);
if(annotation != null){
if(annotation instanceof AgeValidator){
AgeValidator agevalidator = (AgeValidator) annotation;
if(age < agevalidator.min() || age > agevalidator.max()){
throw new RuntimeException("年龄非法");
}
}
}
method.invoke(obj, age);
System.out.println(obj);
}
注解 示例代码 AgeValidator.java
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD})
public @interface AgeValidator {
public int max();
public int min();
}
Person类 setAge 方法调用注解 示例代码
@AgeValidator(min = 18,max = 50)
public void setAge(int age){
this.age = age;
}
( 反射 )Generic 泛型
public static Class getSuperClassGenriType(Class classTemp,int index){
Type type = classTemp.getGenericSuperclass();
if(!(type instanceof ParameterizedType)){
return null;
}
ParameterizedType parameterizedType = (ParameterizedType) type;
Type [] types = parameterizedType.getActualTypeArguments();
if(types == null){
return null;
}
if(index < 0 || index > types.length - 1){
return null;
}
Type arg = types[index];
if(arg instanceof Class){
return (Class) arg;
}
return null;
}
@Test
public void testGetSuperClassGenricType() throws ClassNotFoundException{
String className = "com.reflectiondemo.EmployeeDao";
Class classTemp = Class.forName(className);
Class argClazz = getSuperClassGenriType(classTemp, 0);
System.out.println(argClazz);
argClazz = getSuperClassGenriType(classTemp, 1);
System.out.println(argClazz);
}
代码输出:
class com.reflectiondemo.Enployee
class java.lang.String
Reflection 反射(小结)
Class 是一个类,是一个描述类的类,封装了描述方法的Method , 描述字段的 Field
描述构造器的Constructor 等属性
得到Class 对象
Student.class
student.getClass( );
Class.forName(String className); 较为常用
关于 Method
获取Method
getDeclaredMethods : 得到Method 的数组
getDeclaredMethod(String methodName , Class ... parameterTypes)
调用Method
如果方法是private 修饰的,需要先调用Method 的setAccessible( true ),使其变为可访问
method.invoke(obj, Object ... args );
关于Field
获取Field : getField(String fieldName);
获取Field 的值
setAccessible(true);
field.get(Object obj);
设置Field 的值
field.set(Object obj,Object value);
了解Constructor 和 Annotation
反射和泛型
getGenericSuperClass( ); 获取带泛型参数的父类,返回值 :BaseDao<Employee,String>
Type 的子接口: ParameterizedType
Type[ ] getActualTypeArguments( ) 获取 泛型参数数组
50、动态代理(解决模块化横切关注点)
代理设计模式的原理:使用一个代理将对象包装起来,使用该代理对象取代原始对象
任何对原始对象的调用都要通过代理,代理对象决定是否以及何时将方法调用转到原始对象上
示例代码:
AirthmeticCalculator接口代码
public interface AirthmeticCalculator {
int add(int i ,int j);
int sub(int i ,int j);
void mul(int i ,int j);
void div(int i ,int j);
}
@Test
public void testProxy(){
/** Proxy.newProxyInstance()
* 参数列表:
* ClassLoader loader 由动态代理产生的对象由哪个类加载器进行加载
* 通常和被代理对象使用一样的类加载器
* Class<?>[] : 由动态代理产生的对象必须实现的 接口的Class 数组
* InvocationHandler : 当具体调用代理对象的方法时,将产生什么行为
* */
final AirthmeticCalculator demo = new AirthmeticCalculatorDemo();
AirthmeticCalculator proxy =
(AirthmeticCalculator)
Proxy.newProxyInstance(demo.getClass().getClassLoader()
, new Class[]{AirthmeticCalculator.class},
new InvocationHandler(){
/**
* proxy
* method: 正在被调用的方法
* args: 调用方法时传入的参数
* */
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
System.out.println("The method" + method.getName() +" begin with " + Arrays.asList(args));
Object result = method.invoke(demo, args);
System.out.println("The method" + method.getName() + "end with " + result);
return result;
}
});
proxy.add(5, 5);
int result = proxy.sub(10, 5);
System.out.println(result);
}
/**
* 动态代理的细节
* 需要一个被代理的对象
* Proxy.newInstance( ) 的返回值 一定是被代理对象实现的接口的类型
* 也可以是其他的接口类型
* ClassLoader 类加载器 通常是和被代理对象使用相同的类加载器
* 若代理对象不需要额外实现被代理对象实现的接口以外的接口,可以使用被代理对象的方法 用法:demo.getClass().getInterfaces()
* 代理对象需要实现被代理对象实现的接口以外的接口 用法:new Class[]{AirthmeticCalculator.class,RandomInterface.class}
*
* InvocationHandler 通常是匿名内部类的方式进行 ,需要重写未实现的方法
* 被代理对象需要是final 类型的
* InvocationHandler 的 invoke 方法 中的第一个参数 Object 类型的proxy
* 指正在被返回的那个代理对象,通常不被使用
* */
@Test
public void testProxy2(){
/**
* final 修饰的原因是
* 该局部变量被Object proxy 匿名内部类的重写方法引用
* 而proxy 可能会长时间存在,所以 该demo 需要长的生命周期
* */
final AirthmeticCalculator demo = new AirthmeticCalculatorDemo();
Object proxy = Proxy.newProxyInstance(demo.getClass().getClassLoader(),
demo.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(demo, args);
}
});
}
实例需求:
定义一个Service 接口
void addNew(Person person);
void delete(Integer id);
void update(Person person);
并提供具体实现类
使用动态代理实现2事物操作
在调用具体每个Service 方法前, 都打印:开始事务
方法正常结束, 都打印: 事务提交
若在调用目标方法处异常, 打印:事务回滚
(仅给出部分重要代码)实例代码:
Person类中
private int id;
private String name;
private int age;
无参有参构造方法、重写ToString( )方法
Service接口
void addNew(Person person);
void delete(Integer id);
void update(Person person);
public class PersonServiceDemo {
private Service target = null;
public PersonServiceDemo(Service target) {
this.target = target;
}
public Service getPersonServiceProxy(){
Service proxy = (Service) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println();
System.out.println( " 事务开始 "+"方法:" + method.getName() + " 参数:"+Arrays.asList(args) );
try {
Object result = method.invoke(target, args);
System.out.println(" 事务结束");
return result;
} catch (Exception e) {
e.printStackTrace();
System.out.println(" 回滚事务");
}
return null;
}
});
return proxy;
}
}
public class ServiceDemo implements Service {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
public ServiceDemo() {
persons.put(1001, new Person(1001,"EngineerZhong", 21));
persons.put(1002, new Person(1002,"EngineerYe", 20));
}
public void addNew(Person person) {
persons.put(person.getId(), person);
}
public void delete(Integer id) {
if(id == 1001){
throw new RuntimeException( id +"不能被删除");
}
persons.remove(id);
}
public void update(Person person) {
persons.put(person.getId(), person);
}
public static Map<Integer,Person> getMapValue(){
return persons;
}
}
@Test
public void testProxyDate(){
Service target = new ServiceDemo();
Service proxy = new PersonServiceDemo(target).getPersonServiceProxy();
System.out.println(ServiceDemo.getMapValue());
proxy.addNew(new Person(1003,"EngineerZhong",20));
System.out.println(ServiceDemo.getMapValue());
proxy.delete(1001);
System.out.println(ServiceDemo.getMapValue());
proxy.update(new Person(1002, "EngineerZhongAndeYe", 21));
System.out.println(ServiceDemo.getMapValue());
}
更新时间:2016年10月4日