Spring总结
一、Spring中JDK的动态代理
1、接口类(抽象角色)
package www.csdn.SpringJDK.proxy;
//抽象主题角色
public interface SayBey {
public void say(String content);
}
2、实现类(真是角色)
package www.csdn.SpringJDK.proxy;
//真实主题角色
public class SayBeyImpl implements SayBey,Good {
public void say(String content) {
System.out.println("say:"+content);
}
public void good() {
System.out.println("很好!");
}
}
3、JDK代理
package www.csdn.SpringJDK.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler{
//要代理的对象
private Object target;
//创建目标对象的代理对象
public Object createProxyInstance(Object target){
this.target=target;//代理的目标对象
//创建代理对象
//1、定义类的加载器(第一个参数)
//2、代理类要实现的接口列表(第二个参数)
//3、指派方法调用的调用处理程序
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* proxy:调用方法的代理实例;
* method:对于代理实例调用接口方法的Method实例;
* args:方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//代理的对象
System.out.println("代理的对象:"+proxy.getClass());
//方法的参数
if(args!=null&&args.length>0){
for(Object obj:args){
System.out.println("方法的参数:"+obj);
}
}
//方法的名称
System.out.println(method.getName());
//声明返回值
Object returnValue=null;
beforeMethod();
//执行目标方法
returnValue = method.invoke(target, args);
afterMethod();
//修改返回值
return returnValue;
}
public void beforeMethod(){
System.out.println("====目标方法执行之前");
}
public void afterMethod(){
System.out.println("====目标方法执行之后");
}
}
4、测试类
package www.csdn.SpringJDK.proxy;
import org.junit.Test;
public class SayTest {
@Test
public void say(){
//真实主题角色
SayBeyImpl sayBeyImpl=new SayBeyImpl();
//代理角色
JDKProxy jdkProxy=new JDKProxy();
//SayBey sayBey=(SayBey) jdkProxy.createProxyInstance(sayBeyImpl);
Good good=(Good) jdkProxy.createProxyInstance(sayBeyImpl);
//sayBey.say("haahahhaha");
good.good();
}
}
5、可以实现多个接口
package www.csdn.SpringJDK.proxy;
//多个接口的测试
public interface Good {
public void good();
}
二、Spring中事务代理
1、创建一个接口
package www.csdn.spring.proxy;
public interface UserDao {
public void save(Object obj);
public void update(Object obj);
public void delete(Object obj);
public void getObjects();
}
2、实现接口中的方法
package www.csdn.spring.proxy;
public class UserDaoImpl implements UserDao {
public void save(Object obj) {
System.out.println("保存实体");
}
public void update(Object obj) {
System.out.println("更新实体");
}
public void delete(Object obj) {
System.out.println("删除实体");
}
public void getObjects() {
System.out.println("查询所有");
}
}
3、代理类
package www.csdn.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TransactionProxy implements InvocationHandler {
private Object target;
public Object createProxyInstance(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 {
Object returnValue = null;
String mName = method.getName();
if ("save".equals(mName) || "update".equals(mName)
|| "delete".equals(mName)) {
beforeMethod();
returnValue = method.invoke(target, args);
afterMethod();
} else {
returnValue = method.invoke(target, args);
}
return returnValue;
}
private void afterMethod() {
System.out.println("commit");
}
private void beforeMethod() {
System.out.println("start");
}
}
4、测试类
package www.csdn.spring.proxy;
import org.junit.Test;
public class UserTest {
@Test
public void user(){
UserDaoImpl userDaoImpl=new UserDaoImpl();
TransactionProxy proxy=new TransactionProxy();
UserDao userDao=(UserDao) proxy.createProxyInstance(userDaoImpl);
userDao.delete(null);
userDao.save(null);
userDao.update(null);
userDao.getObjects();
}
}
三、Spring中的Cglib代理
1、创建一个真是主题角色
package www.csdn.cglib.proxy;
public class SayGoodBeyImpl {
public void sayGoodBey(String content){
System.out.println("say: "+content);
}
}
2、创建一个Cglib代理
package www.csdn.cglib.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor {
/**
* proxy:目标对象代理的实例
* method:目标对象调用父类方法的method实例
* args:调用父类方法传递参数
* methodProxy:代理的方法去调用目标方法
*/
//目标对象
private Object target;
//创建目标对象
public Object createProxyInstance(Object target){
this.target=target;
Enhancer enhancer=new Enhancer();//用于生成代理对象
enhancer.setSuperclass(target.getClass());//用于设置代理对象的父亲
enhancer.setCallback(this);//设置回调
return enhancer.create();//创建代理对象
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object returnValue=null;
returnValue=methodProxy.invoke(target, args);
return returnValue;
}
}
3、测试类
package www.csdn.cglib.proxy;
import org.junit.Test;
public class TestCglib {
@Test
public void say(){
//真实主题角色
SayGoodBeyImpl goodBeyImpl=new SayGoodBeyImpl();
//代理处理
CglibProxy cglibProxy=new CglibProxy();
SayGoodBeyImpl proxy=(SayGoodBeyImpl) cglibProxy.createProxyInstance(goodBeyImpl);
proxy.sayGoodBey("额呵呵呵额呵呵饿汉");
}
}
四、Spring中的通知
前置通知
package www.csdn.spring.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdviceMethodImpl implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("------开始事务------");
}
}
后置通知
package www.csdn.spring.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterAdviceImpl implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
String mName=method.getName();
if("save".equals(mName)|| "delete".equals(mName) || "update".equals(mName)){
System.out.println("-----提交事务-----");
}
}
}
环绕通知
package www.csdn.spring.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdviceImpl implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
Object returnValue;
beforeMethod();
returnValue=invocation.proceed();
afterMethod();
return returnValue;
}
private void afterMethod() {
System.out.println("结束日志记录");
}
private void beforeMethod() {
System.out.println("开始日志记录");
}
}
引入通知
接口:
package www.csdn.spring.advice;
import java.util.Date;
public interface AuditableService {
public Date getLastDate() ;
public void setLastDate(Date lastDate) ;
}
实现类
package www.csdn.spring.advice;
import java.util.Date;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
public class AuditableIntroductionInterceptor extends DelegatingIntroductionInterceptor implements AuditableService {
/**
*
*/
private static final long serialVersionUID = 1L;
//封装添加的属性
public Date lastDate;
//set get方法的重写
public Date getLastDate() {
// TODO Auto-generated method stub
return lastDate;
}
public void setLastDate(Date lastDate) {
this.lastDate=lastDate;
}
}
测试类
package www.csdn.spring.advice;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AdviceTest {
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring*.xml");
UserDao userDao=context.getBean("proxyFactoryBean", UserDao.class);
userDao.delete(null);
userDao.save(null);
try{
userDao.update(null);
}catch(Exception e){
e.printStackTrace();
}
userDao.getObjects();
}
@Test
public void test2(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-re*.xml");
//基于接口的代理 jdk的动态代理
UserDao userDao = (UserDao) ac.getBean("proxyFactoryBean"); //= ac.getBean("userServiceImpl",UserServiceImpl.class);
userDao.delete(null);
userDao.save(null);
try{
userDao.update(null);
}catch (Exception e) {
//e.printStackTrace();
}
userDao.getObjects();
//创建的引入通知
/* AuditableService aii = (AuditableService) userService ;
aii.setLastDate(new Date());
System.out.println(aii.getLastDate());*/
}
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通知 -->
<bean id="beforeAdviceMethodImpl" class="www.csdn.spring.advice.BeforeAdviceMethodImpl"/>
<bean id="afterAdviceImpl" class="www.csdn.spring.advice.AfterAdviceImpl"/>
<bean id="aroundAdviceImpl" class="www.csdn.spring.advice.AroundAdviceImpl"/>
<bean id="throwsAdviceImpl" class="www.csdn.spring.advice.ThrowsAdviceImpl"/>
<!-- 配置bean -->
<bean id="userDaoImpl" class="www.csdn.spring.advice.UserDaoImpl"/>
<!-- 代理工厂 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理目标对象 -->
<property name="target" ref="userDaoImpl"/>
<!-- 代理的抽象主题 -->
<property name="proxyInterfaces">
<array>
<value>www.csdn.spring.advice.UserDao</value>
</array>
</property>
<!-- 通知 -->
<property name="interceptorNames">
<array>
<value>beforeAdviceMethodImpl</value>
<value>afterAdviceImpl</value>
<value>aroundAdviceImpl</value>
<value>throwsAdviceImpl</value>
</array>
</property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通知 -->
<bean id="beforeAdviceMethodImpl" class="www.csdn.spring.advice.BeforeAdviceMethodImpl"/>
<bean id="afterAdviceImpl" class="www.csdn.spring.advice.AfterAdviceImpl"/>
<bean id="aroundAdviceImpl" class="www.csdn.spring.advice.AroundAdviceImpl"/>
<bean id="throwsAdviceImpl" class="www.csdn.spring.advice.ThrowsAdviceImpl"/>
<!--引入通知 -->
<bean id="auditableAdvice" class="www.csdn.spring.advice.AuditableIntroductionInterceptor"/>
<!-- 配置bean -->
<bean id="userDaoImpl" class="www.csdn.spring.advice.UserDaoImpl"/>
<!-- 代理工厂 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标对象 -->
<property name="target" ref="userDaoImpl"/>
<!-- 代理的抽象主题 -->
<property name="proxyInterfaces">
<array>
<value>www.csdn.spring.advice.UserDao</value>
<!-- 引入引入通知的接口 -->
<value>www.csdn.spring.advice.AuditableService</value>
</array>
</property>
<!-- 通知 -->
<property name="interceptorNames">
<array>
<!-- 正则表达式 -->
<value>regexpMethodPointcutAdvisor</value>
</array>
</property>
</bean>
<bean id="regexpMethodPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns">
<array>
<!-- .* www.csdn.spring.Service.* 包名类名是 任意-->
<value>.+\.save</value>
<value>www.*\.UserService\.dele.*</value>
<value>.*update</value>
</array>
</property>
<property name="advice" ref="aroundAdviceImpl"/>
</bean>
</beans>
静态引入配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通知 -->
<bean id="beforeAdviceMethodImpl" class="www.csdn.spring.advice.BeforeAdviceMethodImpl"/>
<bean id="afterAdviceImpl" class="www.csdn.spring.advice.AfterAdviceImpl"/>
<bean id="aroundAdviceImpl" class="www.csdn.spring.advice.AroundAdviceImpl"/>
<bean id="throwsAdviceImpl" class="www.csdn.spring.advice.ThrowsAdviceImpl"/>
<!--引入通知 -->
<bean id="auditableAdvice" class="www.csdn.spring.advice.AuditableIntroductionInterceptor"/>
<!-- 配置bean -->
<bean id="userDaoImpl" class="www.csdn.spring.advice.UserDaoImpl"/>
<!-- 代理工厂 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标对象 -->
<property name="target" ref="userDaoImpl"/>
<!-- 代理的抽象主题 -->
<property name="proxyInterfaces">
<array>
<value>www.csdn.spring.advice.UserDao</value>
<!-- 引入引入通知的接口 -->
<value>www.csdn.spring.advice.AuditableService</value>
</array>
</property>
<!-- 通知 -->
<property name="interceptorNames">
<array>
<value>beforeAdviceMethodImpl</value>
<value>afterAdviceImpl</value>
<value>throwsAdviceImpl</value>
<!-- <value>aroundadvice</value> -->
<value>nameMatchMethodPointcutAdvisor</value>
<!-- 引入通知-->
<value>auditableAdvice</value>
</array>
</property>
</bean>
<bean id="nameMatchMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedNames">
<array>
<value>save</value>
<value>update</value>
<value>del*</value>
</array>
</property>
<property name="advice" ref="aroundAdvice"/>
</bean>
</beans>