静态代理、动态代理、Spring AOP面向切面编程(spring动态代理)、spring动态代理注解版

梦想与她 提交于 2019-12-04 06:51:46

目录

静态代理

列:实现静态代理

代理接口User.java

目标对象 实际业务逻辑实现方法UserImpl.java

代理类UserProxy.java

测试

动态代理

列: 实现动态代理

创建po对象

 创建dao

创建代理类 MyProxy.java

测试

Spring Aop 面向切面编程(spring动态代理)

列:aop练习

导包

User.java

UserDao.java

MyAspect.java切面

bean.xml实现

Spring AOP面向切面编程(spring动态代理注解版)

列:spring动态代理注解版

导包

User.java

UserDao.java

UserDaoImpl.java

beans.xml

MyAspect.java

Test.java


静态代理

列:实现静态代理

代理接口User.java

public interface User {
      /*
       * 业务接口
       * */
	public void work(String workName);
	public void doing();  //增加接口
}

目标对象 实际业务逻辑实现方法UserImpl.java

public class UserImpl implements User{

	@Override
	public void work(String workName) {
		// TODO Auto-generated method stub
		 System.out.println("老王 "+ ".");
	}

	@Override
	public void doing() {
		// TODO Auto-generated method stub
		
	}
}

代理类UserProxy.java

实现业务逻辑接口,接收一个实际业务处理对象

public class UserProxy implements User{
    private User user;
	public UserProxy(User user) {
		super();
		this.user = user;
	}

	@Override
	public void work(String workName) {
		// TODO Auto-generated method stub
		check();
		user.work(workName);
		printLog();
	}
	@Override
	public void doing() {
	}
	private void printLog() {
		// TODO Auto-generated method stub
		System.out.println("权限验证");
		
	}

	private void check() {
		// TODO Auto-generated method stub
		System.out.println("打印日志");
	}
}

测试

	@org.junit.Test
	public void test1() {
		User userProxy = new UserProxy(new UserImpl());
		userProxy.work("在吃饭");
	}

动态代理

列: 实现动态代理

创建po对象

 创建dao

创建user接口与 接口实现类

 

创建角色接口与 接口实现类

创建代理类 MyProxy.java

//3创建代理对象
public class MyProxy implements InvocationHandler{
   private Object object;//3.1生命委托对象
   //3.2 有参数的构造方法 
   public MyProxy(Object object) {
		super();
		this.object = object;
	}
   //3.3得到代理对象
   public  Object getProxyObjectInstance() {
	   //Proxy.newProxyInstance(类加载器,接口,代理对象的实例)
	return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
	   
   }
   //3.4生成代理对象
   /**
	 * 在代理实例上处理方法调用并返回结果
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		check();
		Object retObject=method.invoke(object, args);
		printLog();
		return retObject;
	}
    public void check(){
    	System.out.println("用户权限验证");
    }
    public void printLog(){
    	System.out.println("打印日志");
    }

}

测试

	/**
	 * 测试user代理对象
	 */
	@org.junit.Test
	public void testUserProxyObject() {
    MyProxy myProxy=new MyProxy(new UserDaoImpl());//委托
    UserDao userDao=(UserDao)myProxy.getProxyObjectInstance();//获取代理对象
    userDao.addUser(new User());
    System.out.println();
    String id=userDao.getId();
    System.out.println("id==="+id);
	}
	/**
	 * 测试role代理对象
	 */
	@org.junit.Test
	public void testRoleProxuObject() {
		MyProxy myProxy=new MyProxy(new RoleDaoImpl());
		RoleDao roleDao=(RoleDao)myProxy.getProxyObjectInstance();//获取role代理对象
		int a=roleDao.deleteRole(1);
		System.out.println(a);
		
	}

       

Spring Aop 面向切面编程(spring动态代理)

   Aop 采用横向抽取机制,底层采用JDK动态代理.

  • JointPoint 连接点: 所谓连接点是指哪些被拦截到的点,在spring中,这些点指的就是方法,因为spring只支持方法类型的连接点.  

   详解:通知指业务接口中的方法均为连接点…UserDaoImpl中的方法

  • pointCut 切入点: 所谓切入点是指我们对哪些JoinPoint进行拦截的定义.

   详解:我们对哪些Joinpoint进行拦截的定义,addUser().

  • Advice(通知/增强): 拦截到JointPoint之后所要做的事情就是通知

通知有5种。为分前置通知,后置通知,异常通知,最终通知,环绕通知。  详解:拦截的目标对象的addUser()方法,时机(之前/之后等) 执行,通知切面完成功能.

  • Target 目标对象 :代理的目标对象. UserDaoImpl.
  • 切面aspect :泛指业务逻辑根据动态代理的例子. check(),printLog()可以理解为切面.

列:aop练习

导包

User.java

public class User {
	private String id;
	private String name;

	public User() {
		// TODO Auto-generated constructor stub
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}
}

UserDao.java

/**
 *  代理接口(目标对象实现的接口)
 *
 */
public interface UserDao {
	public void save();
	public void update();
	public void query();
	public void delete(int id);
}

 

public class UserDaoImpl implements UserDao {

	/*
	 * save()是切入点
	 */
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("执行save..");
	}

	public void update() {
		// TODO Auto-generated method stub
		System.out.println("执行update..");
	}

	public void query() {
		// TODO Auto-generated method stub
		System.out.println("执行query.. 发成异常");
		int rs=100/0;
	}

	public void delete(int id) {
		// TODO Auto-generated method stub
		System.out.println("执行delete");
	}
}

MyAspect.java切面

public class MyAspect {
	/**
	 * 切面
	 */
      public void check(){
    	  System.out.println("切面---检查权限 ---前置通知");
      }
      public void writeLog(){
    	  System.out.println("写入日志---后置通知");
      }
      //ProceedingJoinPoint 连接点
      public Object aroud(ProceedingJoinPoint joinPoint) throws Throwable{
    	  System.out.println("前");
    	  System.out.println("连接点方法参数:"+joinPoint.getArgs());//连接点方法参数
    	  //joinPoint.getArgs().length参数长度
    	  for(int i=0;i<joinPoint.getArgs().length;i++){
    		  System.out.println("连接点参数值:"+joinPoint.getArgs()[i]);
    	  }
    	    System.out.println(joinPoint.getTarget());//
    	    Object ret=joinPoint.proceed();//执行连接点 
    	    System.out.println("ret=="+ret);
    	    System.out.println("后");
    	  return ret;
      }
      
       public void afterThrowing(Throwable ex){
    	   System.out.println("异常通知"+ex);
       }
     
       public void after(){
    	   System.out.println("最终通知֪");
       }
}

bean.xml实现

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
    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
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">
  
    <!--1实例化目标对象  -->  
    <!-- 配置目标对象 -->
   <bean id="userDao" class="com.iotek.user.dao.UserDaoImpl"></bean>
   
   <!-- 2实例化切面:将切面交给spring容器管理 -->
   <bean id="myAspect" class="com.iotek.user.dao.MyAspect"></bean>
   
  <!-- 3 命名空间: xmlns:aop="http://www.springframework.org/schema/aop" 
         约束:  http://www.springframework.org/schema/aop 
                http://www.springframework.org/schema/aop/spring-aop.xsd --> 
   <!-- 4 书写代理对象:通过aop的配置完成对目标类产生代理 -->
   <aop:config>
       <!--5 写切入点pointCut     expression:切面表达式 -->
       <aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.save(..))" id="pointcut1"/>
      <aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.update(..))" id="pointcut2"/>
      <aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.delete(..))" id="pointcut3"/>
      <aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.query(..))" id="pointcut4"/>
      
      <!--6 写切面aspect   pointcut-ref:引用切入点名称   -->
       <aop:aspect ref="myAspect">
             <!-- 7通知advice:前置通知 -->
             <aop:before method="check" pointcut-ref="pointcut1"/>
             <!-- 8后置通知 -->
             <aop:after-returning method="writeLog" pointcut-ref="pointcut2"/>
             <!-- 9环绕通知 -->
             <aop:around method="aroud" pointcut-ref="pointcut3"/>
             <!-- 10异常通知 -->
             <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
             <!-- 11最终通知 (不管有无异常都会执行) -->
             <aop:after method="after" pointcut-ref="pointcut4"/>
       </aop:aspect>
   </aop:config>
</beans>

测试

public class SpringTest {
	/**
	 *  前置通知测试
	 */
    @Test 
	public void test1(){
		ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
		UserDao userDao=(UserDao)context.getBean("userDao");
		userDao.save();
		userDao.update();
	}
    /**
     * 后置通知测试
     */
    @Test 
   	public void test2(){
   		ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
   		UserDao userDao=(UserDao)context.getBean("userDao");
   		userDao.update();
   	}
    /**
     *  环绕通知测试
     */
    @Test 
   	public void test3(){
   		ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
   		UserDao userDao=(UserDao)context.getBean("userDao");
   		
   		userDao.delete(100);
   	}
    /**
     * 异常通知
     */
    @Test 
   	public void test4(){
   		ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
   		UserDao userDao=(UserDao)context.getBean("userDao");
   		
   		userDao.query();
   	}
}

结果:

test3结果
标题test4结果

Spring AOP面向切面编程(spring动态代理注解版)

列:spring动态代理注解版

导包

User.java

UserDao.java

public interface UserDao {
    public void save();
    public void delete();
    public void update();
    public void query();
}

 

UserDaoImpl.java

@Component(value="userDaoImpl")//注解版实例化
public class UserDaoImpl implements UserDao{

	@Override
	public void save() {
		// TODO Auto-generated method stub
		 System.out.println("UserDaoImpl save");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		 System.out.println("UserDaoImpl delete");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		 System.out.println("UserDaoImpl update");
	}

	@Override
	public void query() {
		// TODO Auto-generated method stub
		//int a=1/0;
		 System.out.println("UserDaoImpl query");
	}

}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">

		          
   	<!--1注解装配  xmlns:context="http://www.springframework.org/schema/context"
	     http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd" -->
		<!-- 扫描包下的所有的类 -->
		<context:component-scan base-package="com.lws"></context:component-scan>
		
	<!-- 2添加aop命名空间 xmlns:aop="http://www.springframework.org/schema/aop" 
       引用aop约束http://www.springframework.org/schema/aop 
	 http://www.springframework.org/schema/aop/spring-aop.xsd -->	
	 
	<!-- 3开启注解版aop配置(启用aspectj对象Annotation支持) -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

MyAspect.java

@Component//实例化切面
@Aspect
public class MyAspect {
	//配置切入点方法
	@Pointcut("execution( * com.lws.dao.UserDaoImpl.*(..))")
	public void myAspectMetod() {
		System.out.println("我是切入点");
	}
	
	//1前置通知
	@Before(value="myAspectMetod()")
	 public void check(){
		 System.out.println("权限验证");
	 }
	//2后置通知
	@After(value="myAspectMetod()")
	 public void printLog(){
		 System.out.println("写入日志文件");
	 }
	//3环绕通知
	@Around(value="myAspectMetod()")
	 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		// System.out.println("前");
		 check();
		 Object obj=joinPoint.proceed();   //执行方法
		 printLog();
		// System.out.println("后");
		 return obj;
	 }
	//4异常通知
	@AfterThrowing(value="myAspectMetod()",throwing="ex")
	 public void afterThrowing(Throwable ex){
		 System.out.println("异常抛出通知"+ex);
	 }
	 //5最终通知一定会被执行的通知
	@AfterReturning(value="myAspectMetod()", returning="object")
	 public void afterReturning(Object object){
		 System.out.println("最终通知"+object);
	 }
}

Test.java

public class Test {
	private ClassPathXmlApplicationContext context;
	@Before
	public void init() {
		context=new ClassPathXmlApplicationContext("beans.xml");
	}
	/**
	 * 8前置通知 
	 */
	@org.junit.Test
	public void beforeTest() {
		UserDao ud=(UserDao)context.getBean("userDaoImpl");
		ud.save();
		System.out.println(ud);
	}
	/**
	 * 8.2后置通知 
	 */
	@org.junit.Test
	public void afterTest() {
		UserDao ud=(UserDao)context.getBean("userDaoImpl");
		ud.update();
		System.out.println(ud);
	}	
	/**
	 * 8.3环绕通知
	 */
	@org.junit.Test
	public void aroundTest() {
		UserDao ud=(UserDao)context.getBean("userDaoImpl");
		ud.delete();
		System.out.println(ud);
	}	
	/**
	 * 8.4异常通知
	 */
	@org.junit.Test
	public void exTest() {
		UserDao ud=(UserDao)context.getBean("userDaoImpl");
		ud.query();
		System.out.println(ud);
	}
	/**
	 * 8.5一定会被执行的
	 */
	@org.junit.Test
	public void uTest() {
		UserDao ud=(UserDao)context.getBean("userDaoImpl");
		ud.query();
		System.out.println(ud);
	}
}

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!