张老师详解代理的观后笔记,以及一些基础知识

代理的作用就相当于加壳的作用,方法调用也要变为第二个才行!


代理的架构图,其中要注意代理类和 接口之间是虚线,代表着继承


生活中的代理
Ø武汉人从武汉的代理商手中买联想电脑和直接跑到北京传智播客旁边来找联想总部买电脑,你觉得最终的主体业务目标有什么区别吗?基本上一样吧,都解决了核心问题,但是,一点区别都没有吗?从代理商那里买真的一点好处都没有吗?

程序中的代理
Ø要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?
Ø编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。(参看下页的原理图)
Ø如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能(如:测试程序执行速率)很容易,以后运行一段时间后,又想去掉系统功能(如:测试程序执行速率)也很容易。

AOP
l系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面,如下所示:

                              安全       事务         日志

StudentService  ------|----------|------------|-------------

CourseService   ------|----------|------------|-------------

MiscService      ------|----------|------------|-------------

l用具体的程序代码描述交叉业务:

method1         method2          method3

{                      {                       {

------------------------------------------------------切面

....            ....              ......

------------------------------------------------------切面

}                       }                       }

l交叉业务的编程问题即为面向方面的编程(Aspect oriented program ,简称AOP),AOP的目标就是要使交叉业务模块化。可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:

------------------------------------------------------切面      

func1         func2            func3

{             {                {

....            ....              ......

}             }                }

------------------------------------------------------切面

l使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术。


只要是面向方面的编程就要涉及到代理!

(技巧) clazzProxy  前面看到 clazz 就是一份字节码

要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!写成百上千个代理类,是不是太累!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中

 
 
java.lang.reflect.Proxy 动态生成代理类             英语学得好的人在编程的时候效率会很高



拼凑组字符串用 
String'Builder这个效率高点 单线程的情况下用这个
StringBuffer  这个多线程效率高,                                              都支持可变的字符串,都支持,改变字符串

5个线程调用main方法,相当于有5个main方法同时运行,每个main方法有自己的StringBuilder变量 ,各是各的变量 彼此不受影响,不受其他线程的影响就不用考虑线程安全的问题!不考虑安全的问题,效率就高
StringBuffer就算没有多线程,还要考虑线程安全,就算很安全,要进行安全处理

目标类没有实现接口,那么我们的动态类就需要借助第三方工具,因为哦我们不知道目标类里面有什么方法吗,也就没法动态的代理  用到了CGLIB这个类 生成目标类的子类、

调用目标前,调用后,或者catch块之中

jvm虚拟中出来的是从内存中产生的class字节码文件,没有类加载器,但是我们创建的时候一定要指定一个加载器,以后找到的话好有归属,方便调用

假期的话如果规划好,静养 或者哪里有好的学生活动,国家组织的省里面组织的,公益社团的都可以去,这样的话不至于浪费时间,蹉跎了时间,近高人好事好地方得 好指点,现在做的好更应该做的是,以后也能做的好,给以后清晰的规划,这样的话不至于浪费太多的时间,而且能在现在给以后给美好做出更多的贡献,好的时候要想好如何给自己做好规划,不是一直冲着做,胡乱的做,毫无顾忌的做,创造为以后有力环境的做,找更多的高人,借助更多国家的机会,领导的机会和他们的帮助,想干但不是乱来,一定好好的做,谨慎的做,整合利用好周围资源利于以后的做,绝不乱为而是为好做得好走的高,现在创造更好的明天,而不仅仅是简单的努力而已,现在条件不创造更好的明天就是对不起自己,一定要比要呢黑心的,还有世界上那些无耻的国家的人好,不仅仅是某方面国人的旗手更是别国赞叹的国家的荣耀,做得好,巧妙的走得好,而且是巧妙的走的高,不是乱来。是精明的前进,所坐的一切都能有利于自己,都有利于以后的长远,而不是口头的长远,自己搞的活动,自己搞的项目,自己在学校付出的努力得到的回报差的太远,以后的岁月中补回来,那些一旁只会嘲笑的所谓的同窗你们只有欣赏别人做好走的高的份,为国为民为荣誉,一定让伟大长存!荣威不止 一定不止 长流长流! 绵延威严,摒弃蹉跎 加大脚步 完成伟大的使命

程序注意技巧
char[] cha = string.toCharArray();
// Char[] cha = string.getchaes();// byte数组是 整数兄弟


// System.out.println("a".equals(cha[0])); //false
// System.out.println(cha[0].equals('a'));报错
System.out.println(cha[0]=='a');// ture

String[] file = oldFile.list();// 创建list文件列表得到所有的文件和目录

//File.separator 表示程序运行的反斜杠 

StringBuilder stringBuilder = new StringBuilder();
用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer 要快


BufferedReader fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
读取的同时将字符集设置成 UTF-8;
一.内部类
  1.什么是内部类: 在另一个类内部定义的类, 就是内部类
  •  2.创建方式 Outer.Inner inner = new Outer().new Inner();
  3.调用内部类的方法和属性的方式和外部类一样, 直接用点语法就可以了
  4.内部类方法中如果直接引用一个变量, 会先在栈内存中找, 如果找不到就会找内部类的成员属性, 如果再没有, 那么找外部类的成员属性
  5.在内部类的方法中, 如果在属性前加this关键字, 那么将强制访问内部类的成员属性
  •  6.如果要在内部类的方法中访问外部类的成员, 那需要 外部类类名.this.成员名.
  7.外部类不能调用内部类的成员, 因为外部类创建的时候,  内部类不一定存在, 成员也没有初始化
  8.如果外部类中要使用内部类的成员, 必须先创建内部类对象
  9.在什么时候使用内部类呢.?
    1).在某种情况下, 必须有另外一个对象先创建, 才能创建想要的对象的时候.
    2).一般内部类能解决的问题, 用2个外部类也能解决
   
二.方法中的内部类
  1.方法中也可以定义内部类
  2.方法中定义的内部类, 只能在该方法中使用, 创建方式和普通类一样.
  3.方法中的内部类, 必须先定义类, 再创建对象. 因为方法运行到类定义代码的时候才加载类, 如果先创建对象, 会找不到符号
  4.方法中内部类如果需要访问外部方法的局部变量, 局部变量需要定义成final

final关键字
 1.final修饰的类是最终的类, 不能被继承
 2.fianl修饰的方法是最终方法, 不能被重写
 3.final修饰的变量时最终变量, 不能被重新赋值
  1).注意: 在变量引用一个对象的时候, 用final修饰这个变量, 只是变量的地址不能改变, 对象是可以改变的
 4.public static final共同修饰一个属性时, 这个属性就变成了全局常量, 一般都大写

++++++匿名内部类中调用外部方法中的局部变量, 变量需要final, 因为这个类对象的生命周期有可能比局部变量的生命周期长++++++

有抽象方法的类, 必须是一个抽象类
 6.有的时候, 我们会将一个没有抽象方法的类, 定义为抽象类, 目的就是不让别人创建对象

finally: 只要执行了try,那么finally中的代码无论如何都会执行
 5.三种异常信息打印方式
  1).e.printStackTrace(): 类名, message, 位置
  2).getMessage(), 只获得message部分
  3).直接打印e, 相当于调用e.toString(), 由于Throwable重写了toString(), 也就能打出异常的简单信息(类名 + message)
 6.子类不能抛出比父类更多的异常
 7.处理多个异常: 将多个异常放在多个catch中(注意顺序问题), 或者在throws后面加逗号, 声明多个.
 8.嵌套: 如果finally中多行代码都必须执行, 而其中又有一些代码会抛异常, 这些初异常的代码也要使用try...finally

笔试题: final, finally, finalize的区别
  1.final:
   1).final是最终的, 不可改变的意思
   2).final修饰类, 不能被继承
   3).final方法, 不能重写
   4).final变量, 变量内存的值不能改变, 基本数据类型变量中直接存值, 引用数据类型存的是地址
  2.finalize:
   1).虚拟机在对象销毁之前会调用finalize方法, 这个方法定义在Object
  3.finally:
   1).和try配合使用.finally中的代码一定会执行.除非System.exit(0);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值