注解与代理模式
相关介绍
Annotation就是嵌入在代码中的标记,补充代码功能,可以修饰包,类,方法,变量
实际开发中,基于注解可以替换配置文件
框架 = 注解 + 反射 + 设计模式的集合
/**
- 1,注解的自定义,参照SuppressWarnings来定义注解,
- 2,注解的使用是施加在某个类上或是方法上,通过反射,可以读出注解中给出的值才有意义。
- 3,元注解:
-
Retention:指明修饰的注解的生命周期,有三种状态:
-
SOURCE:javac指令编译后,在.class文件中不会保留这个注解,被编译器丢弃。
-
CLASS:编译器编译后保留在.class文件当中,但是不会继续保留到执行时候,
-
不存保留到内存当中,注解定义默认是CLASS
-
RUNTIME:注解被加载到内存中,可以通过反射来读取
-
Target:用于指定被修饰的注解可以修饰哪些程序元素
-
TYPE:类,接口
-
FIELD
-
METHOD
-
.
-
.
-
.
-
Documented:表示所修饰的注解,被javadoc解析时保留进文档中
-
Inherited:表示这个注解能被继承,父类有这个注解,子类上也会添加上这个注解
*/
public @interface MyAnnotation {
//这是注解的属性,而不是方法,采用方法的定义方式而已
String value() default "hello";
}
使用反射来获取注解信息
代理模式
静态代理
两个类实现同一个接口,代理类和目标对象的类型在编译时期就已经确定了,不利于程序拓展,
并且每个代理类只为一个接口服务,程序开发过程一定会出现很多代理。
public class ProxyTest {
public static void main(String[] args) {
//new一个代理类对象,传进去一个被代理类对象
ProxyPerson proxyPerson = new ProxyPerson(new RealStar());
//代理类对象干活
proxyPerson.confer();
proxyPerson.signContract();
proxyPerson.order();
//有些工作干不了
proxyPerson.sing();
proxyPerson.collectMoney();
}
}
interface Star{
void confer();//面基
void signContract();//签合同
void sing();//唱歌
void collectMoney();//收钱
}
//被代理类
class RealStar implements Star{
@Override
public void confer() {
}
@Override
public void signContract() {
}
@Override
public void sing() {
System.out.println("明星唱歌~~~~");
}
@Override
public void collectMoney() {
}
}
//代理类--经纪人
class ProxyPerson implements Star{
private Star real;
public ProxyPerson(Star real) {
this.real = real;
}
@Override
public void confer() {
System.out.println("经纪人面基");
}
@Override
public void signContract() {
System.out.println("经纪人签合同");
}
public void order(){
System.out.println("经纪人定票");
}
@Override
public void sing() {
real.sing();
}
@Override
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
动态代理
通过一个代理类完成全部代理功能
使用场合:
远程方法调用
调试
public class ProxyTest {
/**
* 1.jdk动态代理:要求必须有接口,最终生成的代理类在com.sun.proxy包下,类名为$proxy+数字
* 2.cglib动态代理:可以不要接口,最终生成的代理类会继承被代理类,在同一个包下
* 3.dooker zeeker 要用cglib动态代理,因为会在同一个包下。?????
* @param args
*/
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//proxyInstance可以转为Human,而不能转为SuperMan,
// 否则,代理类与被代理类是一个类,只是借用被代理类的实现接口
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
//代理类中没有直接声明与代理类一样的方法,但是调用的确实被代理类的方法,
//会自动执行被代理类的方法
//只需要提供一个被代理类,就能实现这种动态代理!!!!
String belief = proxyInstance.getBelief();
System.out.println(belief);
proxyInstance.eat("四川麻辣烫");
}
}
interface Human{
String getBelief();
void eat(String food);
}
//被代理类
class SuperMan implements Human{
@Override
public String getBelief() {
return "I believe I can fly!!";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃" + food);
}
}
/**
* 1.如何根据加载到内存中的被代理类,动态的创建代理类及其对象
* 2.当通过代理的对象调用方法时,如何动态的调用被代理类中的同名方法
*
*/
//我们使用工厂模式,创建一个工厂类,
class ProxyFactory{
//调用此方法返回一个代理类对象,解决问题1
public static Object getProxyInstance(Object object){
//object指向被代理类的对象,这里不能返回Human,写死了,要用一个代理对象代理多个类
//代理类的实例是通过这样的方式创建得到,类的加载器以及实现的接口都与被代理对象的一致
//当通过代理的对象调用方法时,动态的调用被代理类中的同名方法
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(object);
/**
* 1.指定加载动态生成的代理类的类加载器,随便找一个,只要是系统类加载器就行,
* 所以指定为被代理对象的.class来找到类加载器
* 2.目标类与代理类实现的接口一样
* 3.
*/
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),handler);
}
}
class MyInvocationHandler implements InvocationHandler{
//使用被代理类的对象进行赋值
private Object obj;
public void bind(Object obj) {
this.obj = obj;
}
//当通过代理类的对象调用方法a时,就会自动调用如下方法invoke
//将被代理类要执行的方法a的功能声明在此
//代理类的对象,代理类对象的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* proxy:表示代理对象
* method:即为代理类对象调用的方法,此方法也作为被代理类对象调用的方法,来回切换
* args:表示要执行的方法的参数列表
* obj:被代理对象
*/
//功能实现之前增加一。。。。
//调用目标对象实现功能
Object returnVal = method.invoke(obj, args);
//功能实现之后增加二。。。能够实现AOP
return returnVal;
}
}
标签:对象,void,代理,模式,Override,注解,public
From: https://www.cnblogs.com/napotre/p/16923193.html