自定义注解、自定义ORM框架、常用设计模式分析

访客 阅读:300 2021-03-31 14:15:12 评论:0

一、自定义注解

1.1 什么是注解

Jdk1.5新增新技术,注解为简化代码编写而生。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。

注解分类:内置注解(也成为元注解 jdk 自带注解)、自定义注解(Spring框架)

1.2 内置注解:

@SuppressWarnings   加上它可以在javac编译中去除警告 
@Deprecated   带有它标记的包,方法,字段说明其过时 
@Overricle   打上这个标记说明该方法是将父类的方法重写

1.3 自定义注解

元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:

1.@Target
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明

2.@Retention
表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

3.@Documented

4.@Inherited

自定义注解实例

package com.zzg.annotation; 
 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
 
@Target(value = { ElementType.METHOD, ElementType.TYPE }) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface One { 
	int number() default 0; 
	String name() default ""; 
	String[] arrays(); 
} 
package com.zzg.annotation; 
 
@One(arrays = { "1,2,3,4" },name="annotation",number=10) 
public class OneAnnotation { 
 
} 

二、自定义ORM框架

2.1 自定义orm 注解:

package com.zzg.annotation.orm; 
 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
 
@Target(value = { ElementType.TYPE }) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Table { 
	// 实体对应表名称 
	String name(); 
} 
 
 
package com.zzg.annotation.orm; 
 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Property { 
	// 实体属性对应表字段 
	String name(); 
	 
	int leng(); 
	 
} 

2.2 自定义实体对象

package com.zzg.annotation.orm.entity; 
 
import java.io.Serializable; 
import java.util.Date; 
 
import com.zzg.annotation.orm.Property; 
import com.zzg.annotation.orm.Table; 
 
@SuppressWarnings("serial") 
@Table(name = "t_student") 
public class Student implements Serializable { 
	@Property(leng = 32, name = "sid") 
	private String sid; 
	@Property(leng = 64, name = "name") 
	private String name; 
	@Property(leng = 10, name = "age") 
	private Integer age; 
	@Property(leng = 128, name = "address") 
	private String address; 
	@Property(leng = 0, name = "brithday") 
	private Date brithday; 
	 
	public String getSid() { 
		return sid; 
	} 
	public void setSid(String sid) { 
		this.sid = sid; 
	} 
	public String getName() { 
		return name; 
	} 
	public void setName(String name) { 
		this.name = name; 
	} 
	public Integer getAge() { 
		return age; 
	} 
	public void setAge(Integer age) { 
		this.age = age; 
	} 
	public String getAddress() { 
		return address; 
	} 
	public void setAddress(String address) { 
		this.address = address; 
	} 
	public Date getBrithday() { 
		return brithday; 
	} 
	public void setBrithday(Date brithday) { 
		this.brithday = brithday; 
	} 
	 
	 
 
} 

2.3 orm 框架入口

package com.zzg.annotation.orm; 
 
import java.lang.reflect.Field; 
 
public class ORMDemo { 
 
	public static void main(String[] args) throws Exception { 
		// TODO Auto-generated method stub 
		// 1.反射class 
		Class<?> classForName = Class.forName("com.zzg.annotation.orm.entity.Student"); 
		// 2.获取表名称注解F 
		Table table = classForName.getAnnotation(Table.class); 
		// 3.获取所有的成员属性 
		Field[] declaredFields = classForName.getDeclaredFields(); 
		StringBuffer sf = new StringBuffer(); 
		sf.append(" select "); 
		String fromName = table.name(); 
		for (int i = 0; i < declaredFields.length; i++) { 
			Field field = declaredFields[i]; 
			// 4.属性字段 
			Property sb = field.getAnnotation(Property.class); 
			sf.append(" " + sb.name() + " "); 
			if (i == declaredFields.length - 1) { 
				sf.append(" from "); 
			} else { 
				sf.append(" , "); 
			} 
		} 
		sf.append(" " + fromName); 
		System.out.println(sf.toString()); 
	} 
 
} 

三、常用设计模式

3.1 什么是设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

3.2  设计模式分类

设计模式分为三大类:
        创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
        结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
        行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下:

3.3 设计模式六大原则

1、开闭原则:开闭原则就是说对扩展开放,对修改关闭。 
2、里氏代换原则:任何基类可以出现的地方,子类一定可以出现。 
3、依赖倒转原则:对接口编程,依赖于抽象而不依赖于具体. 
4、接口隔离原则:使用多个隔离的接口,比使用单个接口要好。 
5、迪米特法则:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 
6、合成复用原则:尽量使用合成/聚合的方式,而不是使用继承

3.4 设计模式之单例模式

 单例保证一个对象JVM中只能有一个实例,常见单例 懒汉式、饿汉式
 什么是懒汉式,就是需要的才会去实例化,线程不安全。
 什么是饿汉式,就是当class文件被加载的时候,初始化,天生线程安全。

package com.zzg.pattern; 
 
/** 
 * 设计模式-单例模式(懒汉) 
 * @author Administrator 
 * 
 */ 
public class SingletonOne { 
 
	public static void main(String[] args) { 
		Singleton object1 = Singleton.getSingleton(); 
		Singleton object2 = Singleton.getSingleton(); 
		System.out.println(object1 == object2); 
 
	} 
 
} 
 
class Singleton { 
	// 当需要的才会被实例化 
	private static Singleton singleton; 
 
	private Singleton() { 
 
	} 
 
	synchronized public static Singleton getSingleton() { 
		if (singleton == null) { 
			singleton = new Singleton(); 
		} 
		return singleton; 
	} 
 
} 
package com.zzg.pattern; 
 
/** 
 * 设计模式-单例模式(饿汉) 
 * @author Administrator 
 * 
 */ 
public class SingletonTwo { 
 
	public static void main(String[] args) { 
		SingletonA object1 = SingletonA.getSingleton(); 
		SingletonA object2 = SingletonA.getSingleton(); 
		System.out.println(object1 == object2); 
 
	} 
 
} 
 
class SingletonA { 
	//当class 文件被加载初始化 
	private static SingletonA singleton = new SingletonA(); 
 
	private SingletonA() { 
 
	} 
 
	public static SingletonA getSingleton() { 
		return singleton; 
	} 
} 

3.5 设计模式之工厂模式

目的:实现创建者和调用者分离

package com.zzg.pattern.factory; 
/** 
 * 公共接口方法 
 * @author Administrator 
 * 
 */ 
public interface Car { 
	public void run(); 
 
} 
 
package com.zzg.pattern.factory; 
 
public class Audi implements Car { 
 
	@Override 
	public void run() { 
		// TODO Auto-generated method stub 
		System.out.println("奥迪汽车"); 
	} 
 
} 
 
package com.zzg.pattern.factory; 
 
public class BMW implements Car { 
 
	@Override 
	public void run() { 
		// TODO Auto-generated method stub 
		System.out.println("我是宝马"); 
	} 
 
} 
 
package com.zzg.pattern.factory; 
 
/** 
 * 简单工厂方法 
 *  
 * @author Administrator 
 * 
 */ 
public class CarFactory { 
	public static final String AUDI = "audi"; 
	public static final String BMW = "bmw"; 
 
	public static Car builder(String type) { 
		if (type.equalsIgnoreCase(AUDI)) { 
			return new Audi(); 
		} 
		if (type.equalsIgnoreCase(BMW)) { 
			return new BMW(); 
		} 
		return null; 
	} 
	 
	public static void main(String[] args) { 
		CarFactory.builder(AUDI).run(); 
	} 
 
} 

3.6 设计模式之代理模式

3.6.1 什么是代理模式:

         通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现)  ,AOP核心技术面向切面编程。

图解:

3.6.2 代理分类:静态代理和动态代理

静态代理(静态定义代理类)
动态代理(动态生成代理类)
        Jdk自带动态代理
        Cglib 、javaassist(字节码操作库)

3.6.3  静态代理实例

package com.zzg.pattern.proxy; 
 
public interface Person { 
	public String name(); 
 
} 
 
 
package com.zzg.pattern.proxy; 
 
public class Chinese implements Person { 
 
	@Override 
	public String name() { 
		// TODO Auto-generated method stub 
		System.out.println("我是中国人"); 
		return "中国人"; 
	} 
 
} 
 
 
package com.zzg.pattern.proxy; 
 
public class Proxy implements Person { 
	private Chinese chinese; 
	 
	public Proxy(Chinese chinese) { 
		super(); 
		this.chinese = chinese; 
	} 
 
 
	@Override 
	public String name() { 
		// TODO Auto-generated method stub 
		return chinese.name(); 
	} 
	 
	public static void main(String[] args) { 
		Chinese instance = new Chinese(); 
		Proxy proxy = new Proxy(instance); 
		proxy.name(); 
	} 
 
} 

3.6.4 动态代理之JDK代理

package com.zzg.pattern.proxy.jdk; 
 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 
import com.zzg.pattern.proxy.Chinese; 
import com.zzg.pattern.proxy.Person; 
 
/** 
 * JDK 动态代理 
 * @author Administrator 
 * 
 */ 
public class JDKProxy implements InvocationHandler { 
	private Object object; 
 
	public JDKProxy(Object object) { 
		super(); 
		this.object = object; 
	} 
 
	@Override 
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
		// TODO Auto-generated method stub 
		return method.invoke(object, args); 
	} 
	 
	public static void main(String[] args) { 
		// 接口实例对象 
		Chinese instance = new Chinese(); 
		// JDK 代理实例 
		JDKProxy jdkProxy = new JDKProxy(instance); 
		// 返回接口实例化 
		Person person = (Person) Proxy.newProxyInstance(instance.getClass().getClassLoader(), instance.getClass().getInterfaces(), jdkProxy); 
		// 接口方法调用 
		person.name(); 
	} 
	 
 
} 

3.6.5 cglib 动态代理

package com.zzg.pattern.proxy.cglib; 
 
import java.lang.reflect.Method; 
 
import com.zzg.pattern.proxy.Chinese; 
import com.zzg.pattern.proxy.Person; 
 
import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.MethodInterceptor; 
import net.sf.cglib.proxy.MethodProxy; 
/** 
 * cglib 动态代理 
 * @author Administrator 
 * 
 */ 
public class CglibProxy implements MethodInterceptor { 
 
	@Override 
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 
		// TODO Auto-generated method stub 
		return proxy.invokeSuper(obj, args); 
	} 
	 
	public static void main(String[] args) { 
		CglibProxy cglib = new CglibProxy(); 
		Enhancer enhancer = new Enhancer(); 
		enhancer.setSuperclass(Chinese.class); 
		enhancer.setCallback(cglib); 
		 
		Person person = (Person) enhancer.create(); 
		person.name(); 
	} 
 
} 

总结:JDK动态代理与cglib 动态代理的区别:

jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。
注:asm其实就是java字节码控制.

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
KIKK导航

KIKK导航

排行榜
关注我们

一个IT知识分享的公众号