自定义注解与设计模式
来源:互联网 发布:java实现iis域认证 编辑:程序博客网 时间:2024/06/01 12:31
熟悉注解底层实现原理
完成ORM框架底层原理
常用设计模式
单例、工厂、代理
一.自定义注解
1.1什么是注解?
Jdk1.5新增新技术,注解。很多框架为了简化代码,都会提供有些注解。可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
注解分类:内置注解(也成为元注解jdk自带注解)、自定义注解(Spring框架)
1.2什么是内置注解
Object类有哪些方法?
1.clone方法
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedExcepti
2.getClass方法
final方法,获得运行时类型。
3.toString方法
该方法用得比较多,一般子类都有覆盖。
4.finalize方法
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
5.equals方法
该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。
6.hashCode方法
该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
7.wait方法
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
(1)其他线程调用了该对象的notify方法。
(2)其他线程调用了该对象的notifyAll方法。
(3)其他线程调用了interrupt中断该线程。
(4)时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
8.notify方法
该方法唤醒在该对象上等待的某个线程。
9.notifyAll方法
该方法唤醒在该对象上等待的所有线程。
2 注解的分类
注解按照使用的方式和用途,注解可以分为三大类。
(1)内建注解。
内建注解也称为基本注解,位于java.lang包下。
内建注解有三个:
1,检验重写父类方法:@Override
2,标识方法已经过时:@Deprecated
3,取消编译器警告:@SurppressWarnings
(2)元注解。
元注解就是在注解上添加的注解。
位置:元注解位于java.lang.annotation子包中。
作用:用于修饰其他注解。
元注解有四个:
@Retention,@Target,@Documented,@Inherited。
(3)自定义注解。
需要用到关键字@interface来定义。
比如
(1) @SuppressWarnings 再程序前面加上可以在javac编译中去除警告--阶段是SOURCE
(2) @Deprecated 带有标记的包,方法,字段说明其过时----阶段是SOURCE
(3)@Overricle 打上这个标记说明该方法是将父类的方法重写--阶段是SOURCE
1.1@Overricle 案例演示
@Override
public String toString() {
returnnull;
}
1.2@Deprecated案例演示
new Date().parse("");
1.3 @SuppressWarnings 案例演示
@SuppressWarnings({ "all" })
publicvoid save() {
java.util.Listlist = newArrayList();
}
四个元注解的作用:
@Retention:用来描述被修饰的注解的生命周期。
@Target:用于指定被修饰的注解的适用范围,即被修饰的注解可以用来修饰哪些程序元素。
@Documented:用于指定被修饰的注解将被javadoc工具提取成文档。
@Inherited:用于指定被@Inherited修饰的注解具有继承性。
2.1 单例模式
2.1.1什么是单例模式?
每当new了一个对象,都会在堆内存中会有一个内存地址
单例保证一个对象JVM中只能有一个实例,常见单例懒汉式、饿汉式
什么是懒汉式,就是需要的才会去实例化,线程不安全。
什么是饿汉式,就是当class文件被加载的时候,初始化,天生线程安全。
2.1.2单例写法
懒汉式代码
classSingletonTest {publicstaticvoid main(String[] args) {Singleton sl1 = Singleton.getSingleton();Singleton sl2 = Singleton.getSingleton();System.out.println(sl1 == sl2);}}publicclass Singleton {// 当需要的才会被实例化privatestatic Singleton singleton;// 将构造函数私有化,防止无限new的问题private Singleton() {}Synchronized public static SingletongetSingleton() {if (singleton == null) {singleton = new Singleton();}Return singleton;}}饿汉式代码
class SingletonTest1 {publicstaticvoid main(String[] args) {Singleton1sl1 = Singleton1.getSingleton();Singleton1sl2 = Singleton1.getSingleton();System.out.println((sl1 == sl2)+"-");}}publicclassSingleton1 {//当class 文件被加载初始化privatestaticSingleton1singleton = newSingleton1();private Singleton1() {}publicstaticSingleton1getSingleton() {returnsingleton;}}
2.4工厂模式
2.4.1什么是工厂模式?
实现创建者和调用者分离
2.4.2简单工厂代码
publicinterface Car {publicvoid run();}Public class AoDi implements Car {@Overridepublicvoid run() {System.out.println("奥迪....");}}publicinterface Car {publicvoid run();}Public cclass CarFactory {staticpublic Car createCar(String carName) {Car car = null;if (carName.equals("奥迪")) {car = newAoDi();} elseif (carName.equals("奔驰")) {car = newBenChi();}returncar;}publicstaticvoid main(String[] args) {Car car1 = CarFactory.createCar("奥迪");Car car2 = CarFactory.createCar("奔驰");car1.run();car2.run();}}
2.4.3工厂方法
publicinterface Car {publicvoid run();}publicclassAoDiimplements Car {@Overridepublicvoid run() {System.out.println("奥迪....");}}publicclassBenChiimplements Car {@Overridepublicvoid run() {System.out.println("奔驰....");}}publicclassAoDiChiFactory {staticpublic Car createCar() {returnnewAoDi();}} publicinterfaceBenChiFactory {staticpublic Car createCar() {returnnewBenChi();}} publicclass Main {publicstaticvoid main(String[] args) {Car c1 = AoDiChiFactory.createCar();Car c2 = BenChiFactory.createCar();c1.run();c2.run();}}
2.5代理模式
2.5.1什么是代理?
通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) ,AOP核心技术面向切面编程。
2.5.1代理应用场景
安全代理可以屏蔽真实角色
远程代理远程调用代理类RMI
延迟加载先加载轻量级代理类,真正需要在加载真实
2.5.2代理的分类
静态代理(静态定义代理类)
动态代理(动态生成代理类)
Jdk自带动态代理
Cglib、javaassist(字节码操作库)
2.5.3 静态代理
静态代理需要自己生成代理类
publicclassXiaoMingimplements Hose {@Overridepublicvoidmai() {System.out.println("我是小明,我要买房啦!!!!haha ");}}class Proxy implements Hose {privateXiaoMingxiaoMing;public Proxy(XiaoMingxiaoMing) {this.xiaoMing = xiaoMing;}publicvoidmai() {System.out.println("我是中介看你买房开始啦!");xiaoMing.mai();System.out.println("我是中介看你买房结束啦!");}publicstaticvoid main(String[] args) {Hose proxy = new Proxy(newXiaoMing());proxy.mai();}}
2.5.4JDK动态代理(不需要生成代理类)
实现InvocationHandler就可以了。
publicinterface Hose {/** * * @methodDesc: 功能描述:(买房代理) * @param: * @createTime:2017年8月27日上午2:54:34 * @returnType: void */publicvoidmai();}publicclassXiaoMingimplements Hose {@Overridepublicvoidmai() {System.out.println("我是小明,我要买房啦!!!!haha ");}}publicclassJDKProxyimplementsInvocationHandler {private Object tarjet;publicJDKProxy(Object tarjet) {this.tarjet = tarjet;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {System.out.println("我是房产中介.....开始监听你买房啦!");Object oj = method.invoke(tarjet, args);System.out.println("我是房产中介.....结束监听你买房啦!");returnoj;}}class Test222 {publicstaticvoid main(String[] args) {XiaoMingxiaoMing = newXiaoMing();JDKProxyjdkProxy = newJDKProxy(xiaoMing);Hose hose=(Hose) Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), jdkProxy);hose.mai();}}
2.5.6 CGLIB动态代理
实现
importjava.lang.reflect.Method;importnet.sf.cglib.proxy.Enhancer;importnet.sf.cglib.proxy.MethodInterceptor;importnet.sf.cglib.proxy.MethodProxy;publicclassCglibimplementsMethodInterceptor {@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxymethodProxy) throwsThrowable {System.out.println("我是买房中介,开始监听你买房了....");Object invokeSuper = methodProxy.invokeSuper(o, args);System.out.println("我是买房中介,开结束你买房了....");returninvokeSuper;}}class Test22222 {publicstaticvoid main(String[] args) {Cglibcglib = newCglib();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(XiaoMing.class);enhancer.setCallback(cglib);Hose hose = (Hose) enhancer.create();hose.mai();}}
2.5.7CGLIB与JDK动态代理区别
jdk动态代理是由内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。
注:asm其实就是java字节码控制.
- 自定义注解与设计模式
- 访问注解与自定义注解
- 设计模式&注解随笔
- 自定义注解与使用
- 解析动态代理模式与跟自定义注解配合使用以及事务注解原理
- 《JAVA与模式》之观察者设计模式及自定义监听器
- 注解初体验与自定义注解实战
- Java注解与自定义注解处理器
- 自定义观察者设计模式
- Java注解(三) 自定义注解与提取注解
- Java注解(三) 自定义注解与提取注解
- 设计模式之--迭代器模式(自定义迭代器与STL::find()配合查找链表元素)
- 装饰设计模式---自定义数据源
- spring中自定义注解(annotation)与获取注解
- spring中自定义注解(annotation)与AOP中获取注解
- Spring中自定义注解与AOP中获取注解
- spring中自定义注解(annotation)与AOP中获取注解
- 自定义 Jackson 注解与禁用某一特定的注解
- js如何实现全排列
- sublime修改打开文件的默认语法模版类型
- 使用初始化捕获来把对象移动到闭包
- linux中的自旋锁spinlock和信号量用于线程同步的区别
- Ant自动编译打包&发布 android项目
- 自定义注解与设计模式
- 上台阶
- Wine QQ 安装
- SpringBoot之starter(R)
- 解决apt-get install E: 无法定位软件包问题
- Redis与Memcached的区别
- MSM RF Driver Configuration
- 极简略介绍 javascript 事件代理(事件委托)
- 大数据Spark企业级实战版【学习笔记】-----交互式SQL处理框架Spark SQL