一、自定义注解
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字节码控制.