Java 设计模式

Java 常见的设计模式

  • Proxy 代理模式
  • Factory 工厂模式
  • Singleton 单例模式
  • Delegate 委派模式
  • Strategy 策略模式
  • Prototype 原型模式
  • Template 模板模式
  1. 代理模式是Java最常见的一种设计模式,客户端不是直接调用实际的对象,而是通过代理,来间接调用实际对象。代理模式可分为两种, 静态代理,动态代理

    静态代理:代码实现:

package spring.service;

public interface ProxyService {
	
	void say();

}
package spring.service.impl;

import spring.service.ProxyService;

public class RealProxy implements ProxyService{

	private String name = "shanghai";
	@Override
	public void say() {
		System.out.println(name);
		
	}

}
package spring.service.impl;

import spring.service.ProxyService;

public class Real2Proxy implements ProxyService{

	private String name = "beijing";
	@Override
	public void say() {
		System.out.println(name);
		
	}

}
package spring.service.impl;

import spring.service.ProxyService;

public class ProxyServiceImpl implements ProxyService{

	private ProxyService service;
	
	public ProxyServiceImpl(ProxyService service){
		this.service = service;
	}
	
	@Override
	public void say() {
		service.say();
		
	}

}
package spring.controller;

import spring.service.ProxyService;
import spring.service.impl.ProxyServiceImpl;
import spring.service.impl.Real2Proxy;
import spring.service.impl.RealProxy;

public class ProxyController {
	
	public static void main(String[] args) {
		ProxyService service = new ProxyServiceImpl(new RealProxy());
		service.say();
		
		ProxyService service1 = new ProxyServiceImpl(new Real2Proxy());
		service1.say();
	}

}

动态代理:也叫JDK代理,跟静态代理差不多,也有种叫cglib 代理

package spring.service.impl;

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

/**
 * JDK 代理
 */
public class DynamicProxy implements InvocationHandler{
	
	private Object object;
	
	public DynamicProxy(Object object){
		this.object = object;
	}
	

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		Object result = method.invoke(object, args);
        return result;
	}

}

cglib 代理,要导入 cglib jar,还可以用springcglib 代理

package spring.service.impl;

/**
 * cglib 代理
 * 目前类不能用final 修饰
 * 方法不能用static final 修饰
 */
public class Cglib {
	
	private String name = "java";
	
	public void say(){
		System.out.println(name);
	}

}
package spring.service.impl;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;


public class CglibProxy implements MethodInterceptor{
	
	private Object object;
	
	public CglibProxy(Object object){
		this.object = object;
	}
	
	public Object getProxyInstance(){
		//工具类
		Enhancer en = new Enhancer();
		//设置父类
		en.setSuperclass(object.getClass());
		//设置回调函数
		en.setCallback(this);
		//创建子类,(代理对象)
		return en.create();
	}
	

	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		Object result = method.invoke(object, args);
        return result;
	}

}
package spring.controller;

import spring.service.impl.Cglib;
import spring.service.impl.CglibProxy;

public class ProxyController {
	
	public static void main(String[] args) {
		//静态
//		ProxyService service = new ProxyServiceImpl(new RealProxy());
//		service.say();
//		
//		ProxyService service1 = new ProxyServiceImpl(new Real2Proxy());
//		service1.say();
		
		//JDk代理
//		DynamicProxy proxy = new DynamicProxy(new RealProxy());
//		ProxyService service = (ProxyService) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{ProxyService.class}, proxy);
//		service.say();
		
		//cglib 代理
		Cglib cg = (Cglib) new CglibProxy(new Cglib()).getProxyInstance();
		cg.say();
		
	}

}

总结:三种代理模式各有优缺点和相应的适用范围,主要看目标对象是否实现了接口。以Spring框架所选择的代理模式举例

在Spring的AOP编程中:

如果加入容器的目标对象有实现接口,用JDK代理

如果目标对象没有实现接口,用Cglib代理

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值