SSM-JAVA设计模式(二)

 

2.1.反射

2.1.1无参反射

 

public ReflectServiceImpl getInstance(){
		 ReflectServiceImpl object = null;
		try {
			object = (ReflectServiceImpl)Class.forName("com.gessica.service01.test.ReflectServiceImpl").newInstance();
		
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return object;
	}
    • 给类加载器注册全限类名的ReflectServiceImpl类,
  • newInstance()初始化一个类对象

有参反射

  • public ReflectServiceImpl2 getInstance(){
    		 ReflectServiceImpl2 object = null;
    		try {
    			object = (ReflectServiceImpl2)Class.forName("com.gessica.service01.test.ReflectServiceImpl2").getConstructor(String.class).newInstance("Jessica");
    		
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 
    		return object;
    	}
    通过getConstructor()方法的参数为Sting类型且只有一个(可以有多个),确定这个构造方法。

     

  • 通过getConstructor()方法的参数为Sting类型且只有一个(可以有多个),确定这个构造方法。

2.1.2方法反射

Object reflectMothed() {
		ReflectServiceImpl2 reflectServiceImpl2 = new ReflectServiceImpl2("Jessica2");
		Object invoke = null;
		try {
			method = ReflectServiceImpl2.class.getMethod("sayHello",String.class);
			invoke = method.invoke(reflectServiceImpl2, "Jessica4");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return invoke; 
		
	}
public void sayHello(String name) {
		System.out.println("Hello "+name);
	}

 

    • 获取类ReflectServiceImpl2.class
    • 获取制定方法getMethod("sayHello",String.class);,第一个参数方法名,第二个参数类型
    • 反射方法method.invoke(reflectServiceImpl2, "Jessica4")

 

2.2动态代理模式和责任链模式

2.2.1jdk动态代理

  • 最常用的动态代理有两种:一种是JDK,这是JDK自带的;另一种是CGLIB这是三方技术提供的,目前Spring使用了,但MyBatis还使用了Javassist
  • JDK代理必须使用接口,而CGLIB不需要相对简单拿一些
  • JDK代理
    • 必须实现java.lang.reflect.InvocationHandler接口,里边定义了一个方法invoke(),并提供接口数组用于下挂代理对象

 

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxyExample implements InvocationHandler {
	
	private Object target;

	public Object bind(Object target){
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("调用真实对向前");
		Object object = method.invoke(target, args);
		System.out.println("调用真实对向后");
		return object;
	}

	public static void main(String[] args) {
		 JdkProxyExample jdkProxyExample = new JdkProxyExample();
		 HelloWord helloWord = (HelloWord) jdkProxyExample.bind(new HelloWordImpl());
		 helloWord.sayHelloWord();
	}


}

 运行结果:

调用真实对向前
JDK代理测试HelloWord
调用真实对向后
 

public class HelloWordImpl implements HelloWord {

	public void sayHelloWord() {
		System.out.println("JDK代理测试HelloWord");
	}
}

public interface HelloWord {
	public void sayHelloWord();
}

2.2.2CGBLI动态代理

public class CglibProxyExample implements MethodInterceptor {
	/**
	 * 生成CGLIB代理对象
	 * @param clazz
	 * @return
	 */
	public Object getProxy(Class clazz) {
		//CGLIB 增强类对象
		 Enhancer enhancer = new Enhancer();
		 //设置增强类
		 enhancer.setSuperclass(clazz);
		 //定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor
		 enhancer.setCallback(this);
		 //生成并返回代理对象
		 return enhancer.create();
	}

	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		System.out.println("调用前");
		Object result = arg3.invokeSuper(arg0, arg2);
		System.out.println("调用后");
		return result;
	}
}

测试:

public static void main(String[] args) {
		CglibProxyExample cglibProxyExample = new CglibProxyExample();
		ReflectServiceImpl object = (ReflectServiceImpl) cglibProxyExample.getProxy(ReflectServiceImpl.class);
		object.sayHello("Jessica");
	}

测试结果:

调用前
Hello Jessica
调用后

2.2.3拦截器

1.定义拦截器接口

 

public interface Interceptor {
	//proxy 代理对象, targer 真是对象,method 方法,agrs 参数
	//boobean 返回 true为反射真是对象,false则调用around,最后调用after
	public boolean before(Object proxy,Object targer,Method method,Object[] args );
	public void around(Object proxy,Object targer,Method method,Object[] args );
	public void after(Object proxy,Object targer,Method method,Object[] args );
}

 

2.实现拦截器接口

 

ppublic class MyInterceptor implements Interceptor {

	public boolean before(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("反射方法前逻辑");
		return false;
	}

	public void around(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("取代了被代理方法");

	}

	public void after(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("反射方法后逻辑");
	}

}

 

 

3.在JDK动态代理中使用拦截器

public class InterceptorJdkProxy implements InvocationHandler {
	
	private Object targer;//真实对象
	private String interptorClass;//拦截器权限类名

	public InterceptorJdkProxy(Object targer,String interptorClass){
		this.targer = targer;
		this.interptorClass =interptorClass;
	}
	/**
	  * 绑定委托对象并返回一个(代理占位)
	 * @param targer 真实对象
	 * @param interceptorClass 代理对象【占位】
	 * @return
	 */
	 public static Object bind(Object targer,String interceptorClass) {
		 System.out.println("进入bind");
		 //取代代理对象
		 return Proxy.newProxyInstance(targer.getClass().getClassLoader(), targer.getClass().getInterfaces(), new InterceptorJdkProxy(targer, interceptorClass));
	 }
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if(interptorClass == null) {
			//没有设置拦截器则直接反射原有方法
			return method.invoke(targer, args);
		}
		Object result = null;
		//通过反射生成拦截器
		Interceptor interptor = (Interceptor) Class.forName(interptorClass).newInstance();
		//调用前置方法
		System.out.println("开始调用befer");
		if (interptor.before(proxy, args, method, args)) {
			
			//反射原有对象方法
			result = method.invoke(targer, args);
		} else {//返回false则执行around
			System.out.println("开始调用around");
			interptor.around(proxy, targer, method, args);
		}
		//调用后方法
		System.out.println("开始调用after");
		interptor.after(proxy, targer, method, args);
		return result;
	}
	public static void main(String[] args) {
		HelloWord proxy = (HelloWord) InterceptorJdkProxy.bind(new HelloWordImpl(), "com.gessica.service01.test4.MyInterceptor");
		proxy.sayHelloWord();
	}

 

  • 两个属性一个terger真实对象,另一个拦截器全名
  • 1.bind用JD看中动态代理绑定一个对象,然后返回代理对象
  • 2.如果没有设置拦截器,则返回真实对象
  • 3.准备生成拦截器,调用before方法,返回false则调用around方法
  • 4.调用拦截器after方法

4.运行结果

进入bind

开始调用befer

反射方法前逻辑

开始调用around

取代了被代理方法

开始调用after

反射方法后逻辑

2.2.4责任链模式

当一个对象在一个链上被多个拦截器处理称为责任链模式

 

1.定义三个拦截器

public class Interceptor1 implements Interceptor {

	public boolean before(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("拦截器1的before方法");
		return true;
	}

	public void around(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("取代了被代理方法");

	}

	public void after(Object proxy, Object targer, Method method, Object[] agrs) {
		System.out.println("拦截器1的after方法");
	}

}
。。。

 

 

 

 

 

2.通过InterceptorJdkProxy测试

 

public static void main(String[] args) {
//		HelloWord proxy = (HelloWord) InterceptorJdkProxy.bind(new HelloWordImpl(), "com.gessica.service01.test4.MyInterceptor");
//		proxy.sayHelloWord();
		HelloWord proxy1 = (HelloWord) InterceptorJdkProxy.bind(new HelloWordImpl(), "com.gessica.service01.test4.Interceptor1");
		HelloWord proxy2 = (HelloWord) InterceptorJdkProxy.bind(proxy1, "com.gessica.service01.test4.Interceptor2");
		HelloWord proxy3 = (HelloWord) InterceptorJdkProxy.bind(proxy2, "com.gessica.service01.test4.Interceptor3");
		proxy3.sayHelloWord();
	}

3.运行结果

 

开始调用befer

拦截器3的before方法

开始调用befer

拦截器2的before方法

开始调用befer

拦截器1的before方法

JDK代理测试HelloWord

开始调用after

拦截器1的after方法

开始调用after

拦截器2的after方法

开始调用after

拦截器3的after方法

 

2.3观察者模式

观察者模式又称为发布订阅模式,是对象的行为模式,一对多,多个观察者监视着被观察者

Java中需要继承java.util.Observable类

2.3.1被观察者

public class ProductList extends Observable {
	private List productList = null;//产品列表
	private static ProductList instance;//类唯一实例
	private ProductList() {};
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	/**
	 * 获取实例,产生产品列表
	 * @return
	 */
	public static ProductList getInstance() {
		if (instance == null) {
			instance = new ProductList();
			instance.productList = new  ArrayList();
		}
		return instance;
	}
	/**
	 * 添加观察者
	 * @param observer
	 */
	public void addProductListObervable(Observer observer) {
		this.addObserver(observer);
	}
	/**
	 * 新增产品
	 * @param newProduct
	 */
	public void addProduct(String newProduct) {
		productList.add(newProduct);
		System.out.println("新添了产品:"+newProduct);
		this.setChanged();//设置被观察者对象发生了变化
		this.notifyObservers(newProduct);//通知观察者,并传递新产品
	}
}

 

2.3.2观察者

 

需实现java.util.Observable
public class TaoBaoOberver implements Observer {

	public void update(Observable o, Object arg) {
		String newProduct = (String) arg;
		System.out.println("发布新产品:"+newProduct+"同步到淘宝");

	}

}
。。。

2.3.3测试

ProductList productList = ProductList.getInstance();
		JingdongOberver jingdongOberver = new JingdongOberver();
		TaoBaoOberver taoBaoOberver = new TaoBaoOberver();
		productList.addObserver(taoBaoOberver);
		productList.addObserver(jingdongOberver);
		productList.addProduct("新增产品1");

2.3.4结果

新添了产品:新增产品1

发布新产品:新增产品1同步到京东

发布新产品:新增产品1同步到淘宝

 

2.4工厂模式和抽象工厂模式

 

2.4.1普通工厂(Simple factory)模式

同一产品不同类型,定义一个Iproduct,有Product1,Product2,Product3,Product4生产,是一个大类

2.4.2抽象工厂 (Abstract factory)模式

抽象工厂可以向客户提供一个接口,是客户端不必知道产品的情况下,创建多个创建多个产品组中的产品对象

SSM-JAVA设计模式(二)_第1张图片

 

创建产品

public class IProduct {
	private String name ;
	private String color ;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	
	
}

创建抽象工厂

 

public interface IProductFactory {
	public IProduct createProduct(String productNo);
}

创建具体工厂

public class Product1 implements IProductFactory {

	public IProduct createProduct(String name) {
		System.out.println("具体工厂一:"+name);
		IProduct iProduct = new IProduct();
		iProduct.setName(name);
		iProduct.setColor("red");
		return iProduct;

	}

}

创建公共工厂

public class ProductFactory implements IProductFactory {

	private IProductFactory product;

	public IProduct createProduct(String productNo) {
		char c = productNo.charAt(0);
		if (c == '1') {
			
			product = new Product1();
		}else if (c == '2'){
			product = new Product2();
		}
		if (product != null) {
			return product.createProduct(productNo);
		}
		return null;
	}
	public static void main(String[] args) {
		ProductFactory productFactory = new ProductFactory();
		IProduct createProduct = productFactory.createProduct("1警车");
		System.out.println("颜色:"+createProduct.getColor());
	}

}

测试结果

具体工厂一:1警车

颜色:red

 

2.5建造者(Builder)模式

 

建造者模式属于对象创建模式,可以将一个产品的内部属性与产品的生成过程分割开来,从而是一个建造过程生成具有不同内部属性的产品对象

1.配置类

public class TicketHelper {
	public void buildAdult(String info) {
		System.out.println("构建成年人票逻辑:"+info);
	}
	public void buildChildrenForSeat(String info) {
		System.out.println("构建儿童有坐票逻辑:"+info);
	}
	public void buildChildrenNoSeat(String info) {
		System.out.println("构建儿童无坐票逻辑:"+info);
	}
	public void buildElderly(String info) {
		System.out.println("构建老年人票逻辑:"+info);
	}
	public void buildSoldier(String info) {
		System.out.println("构建军年及家属票逻辑:"+info);
	}
}

 

2.创建Builder

 

public class TicketBuilder {
	public static Object builder(TicketHelper helper) {
		System.out.println("通过TicketHelper构建套票信息");
		return null;
	}
}

 

3.测试

TicketHelper helper = new TicketHelper();
		helper.buildAdult("成年票");
		helper.buildChildrenForSeat("儿童有坐票");
		helper.buildChildrenNoSeat("儿童五坐票");
		helper.buildElderly("老人票");
		helper.buildSoldier("构建军人票");
		TicketBuilder.builder(helper);

4.结果

构建成年人票逻辑:成年票

构建儿童有坐票逻辑:儿童有坐票

构建儿童无坐票逻辑:儿童五坐票

构建老年人票逻辑:老人票

构建军年及家属票逻辑:构建军人票

通过TicketHelper构建套票信息

 

 

 

 

                                                 如有错误或者不当之处,请多指教

 

你可能感兴趣的:(JAVA服务端)