代理模式的来源
解决的小案例(静态代理)
pojo
BigBoss
package com.peng.pojo;
import org.springframework.stereotype.Component;
@Component(value = "bigboss")
public class BigBoss implements SellInterface {
@Override
public void sellAction() {
System.out.println("boss sell home!");
}
}
LinkHome
package com.peng.pojo;
import org.springframework.stereotype.Component;
@Component(value = "bigboss")
public class BigBoss implements SellInterface {
@Override
public void sellAction() {
System.out.println("boss sell home!");
}
}
Manager
package com.peng.pojo;
import org.springframework.stereotype.Component;
@Component(value = "bigboss")
public class BigBoss implements SellInterface {
@Override
public void sellAction() {
System.out.println("boss sell home!");
}
}
SellInterface
package com.peng.pojo;
import org.springframework.stereotype.Component;
@Component(value = "bigboss")
public class BigBoss implements SellInterface {
@Override
public void sellAction() {
System.out.println("boss sell home!");
}
}
test
Test
package com.peng.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.peng.pojo.LinkHome;
public class Test {
@org.junit.Test
public void Test_Agent() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
LinkHome linkhome = (LinkHome) context.getBean("linkhome");
linkhome.sellAction();
}
}
配置文件
代码示例
dao
PersonDao
package com.peng.dao;
import com.peng.pojo.Person;
public interface PersonDao {
void savePerson(Person p);
}
PersonDaoImpl
package com.peng.dao;
import com.peng.pojo.Person;
public interface PersonDao {
void savePerson(Person p);
}
service
PersonService
package com.peng.dao;
import com.peng.pojo.Person;
public interface PersonDao {
void savePerson(Person p);
}
PersonServiceImpl
package com.peng.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.peng.dao.PersonDao;
import com.peng.pojo.Person;
@Service(value = "serviceImpl")
public class PersonServiceImpl implements PersonService {
@Autowired
@Qualifier(value = "personDao")
private PersonDao dao;
@Override
public void savePerson(Person p) {
if (null != dao) {
dao.savePerson(p);
}
}
}
web
PersonServlet
package com.peng.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import com.peng.pojo.Person;
import com.peng.service.PersonService;
@Controller(value = "personServlet")
public class PersonServlet {
@Autowired
@Qualifier(value = "personserviceproxy")
private PersonService proxy;
public void doSomething(Person p) {
proxy.savePerson(p);
}
}
proxy
PersonServiceProxy
package com.peng.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import com.peng.pojo.Person;
import com.peng.service.PersonService;
@Controller(value = "personServlet")
public class PersonServlet {
@Autowired
@Qualifier(value = "personserviceproxy")
private PersonService proxy;
public void doSomething(Person p) {
proxy.savePerson(p);
}
}
manager
Manager
package com.peng.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import com.peng.pojo.Person;
import com.peng.service.PersonService;
@Controller(value = "personServlet")
public class PersonServlet {
@Autowired
@Qualifier(value = "personserviceproxy")
private PersonService proxy;
public void doSomething(Person p) {
proxy.savePerson(p);
}
}
test
Test
package com.peng.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.peng.pojo.Person;
import com.peng.web.PersonServlet;
public class Test {
@org.junit.Test
public void trest1() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("=================懒加载在此之后=================");
Person person = (Person) ac.getBean("person");
PersonServlet servlet = (PersonServlet) ac.getBean("personServlet");
servlet.doSomething(person);
ac.close();
}
}
pojo
Person
package com.peng.pojo;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Scope(value = "singleton")
@Lazy(value = true)
@Component(value = "person")
public class Person {
@Value(value = "张三")
private String name;
@Value(value = "12")
private Integer age;
private Person() {
super();
System.out.println("============构造函数===========");
}
private Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "名称:" + name + ",年龄:" + age;
}
@PostConstruct
public void init() {
System.out.println("=====Person=====init==========");
}
@PreDestroy
public void destory() {
System.out.println("=====Person=====destory==========");
}
}
配置文件
十二月 20, 2017 10:26:03 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 10:26:03 CST 2017]; root of context hierarchy
十二月 20, 2017 10:26:03 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
十二月 20, 2017 10:26:04 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,personserviceproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
=================懒加载在此之后=================
============构造函数===========
=====Person=====init==========
start................
保存了~~名称:张三,年龄:12
commit................
十二月 20, 2017 10:26:05 上午 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 10:26:03 CST 2017]; root of context hierarchy
十二月 20, 2017 10:26:05 上午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,personserviceproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
=====Person=====destory==========
JDK的动态代理方式
关键代码
DynamicProxy
package com.peng.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public abstract class DynamicProxy {
public Object getProxy(final Object obj) {
Object proxy_ob = Proxy.newProxyInstance(obj.getClass()
.getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
/* 被代理的对象的方法任意执行的这里都执行 */
// 执行before方法
before();
// 执行目标方法
Object result = method.invoke(obj, args);
// 执行after方法
after();
return result;
}
});
return proxy_ob;
}
protected abstract void before();
protected abstract void after();
}
PersonDynamicProxy
package com.peng.proxy;
import org.springframework.stereotype.Component;
@Component(value = "persondynamicproxy")
public class PersonDynamicProxy extends DynamicProxy {
@Override
protected void before() {
System.out.println("person-------------------start");
}
@Override
protected void after() {
System.out.println("person-------------------after");
}
}
Test
package com.peng.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.peng.pojo.Person;
import com.peng.web.PersonServlet;
public class Test {
@org.junit.Test
public void trest1() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("=================懒加载在此之后=================");
Person person = (Person) ac.getBean("person");
PersonServlet servlet = (PersonServlet) ac.getBean("personServlet");
servlet.doSomething(person);
ac.close();
}
}
。。。
十二月 20, 2017 11:25:19 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 11:25:19 CST 2017]; root of context hierarchy
十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,persondynamicproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
=================懒加载在此之后=================
============构造函数===========
=====Person=====init==========
person-------------------start
保存了~~名称:张三,年龄:12
person-------------------after
十二月 20, 2017 11:25:19 上午 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 11:25:19 CST 2017]; root of context hierarchy
十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,persondynamicproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
=====Person=====destory==========
Cglib方式的动态代理
例子
package com.peng.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public abstract class DynamicProxy {
public Object getProxy(final Object obj) {
// 创建一个增强器
Enhancer enhancer = new Enhancer();
// 设置父接口
enhancer.setInterfaces(obj.getClass().getInterfaces());
// 设置父类
enhancer.setSuperclass(obj.getClass());
// 设置接口
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("asdfghj");
Object result = arg1.invoke(obj, arg2);
System.out.println("asdfghj");
return result;
}
});
return enhancer.create();
}
protected abstract void before();
protected abstract void after();
}
例子
切面类
package com.peng.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.peng.manager.Manager;
/**
* 切面
*
* @author Administrator
*
*/
@Component(value = "txaspect")
public class TxAspect {
@Autowired
@Qualifier(value = "manager")
Manager manager;
// 此方法当代理对象执行方法的时候去执行
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
manager.start();// 开始事务
// 执行目标方法
Object result = joinPoint.proceed();
manager.commit();// 提交事务
return result;
}
}