zoukankan      html  css  js  c++  java
  • Spring框架学习之第9节

    •  aop编程

    aop(aspect oriented programming)面向切面(方面)编程,是所有对象或者是一类对象编程,核心是(在不增加代码的基础上,还增加新功能)

    汇编(伪机器指令 mov jump)面向机器

    C语言(面向过程)->系统软件(操作系统,数据库,语言本身,杀毒软件,防火墙,驱动)大部分都是用C语言软件写

    语句1;

    语句2;

    C++

    Java语言(面向对象->类-对象)

    class Dog{

        属性;->变量

        行为->函数

    }

    面向切面 spring(->aop)面向很多对象编程

    aop特别提醒:aop编程,实际上在开发框架本身用的很多,在实际项目开发中用的并不是很多,但是将来会越来越多,这是个编程的趋势

    •  aop原理+案例

    aop原理+案例(aop中有很多概念,先不说,当我们讲完案例后,再看概念)

    需求:在调用Test1Service sayHello()前完成日志记录功能,

    在调用Test2Service sayHello()前也要完成日志

    编程说明

    beans.xml

    1. 被代理的对象
    2. 前置通知
    3. 代理对象

    <!!!细节!!!>

    步骤如下:

    1、 定义接口

    2、 编写对象(被代理对象=目标对象)

    3、 编写通知(前置通知在目标方法调用前调用)

    4、 在我们的beans.xml中配置

    4.1、先配置被代理对象=目标对象

    4.2、配置通知

    4.3、配置代理对象是proxyFactoryBean对象实例

    4.3.1、<!—代理接口集--à

    4.3.2、织入通知

    4.3.3、配置被代理对象

    真正的织入发生时动态的,真正的织入发生应该是一个过程,当你在调用被代理对象方法的时候织入发生。

    切入了定义了通知应该在哪些连接点上,定义了前置通知可以在sayHello之前被调用,连接点就会变成切入点,就好像连接点是一个静态的概念而切入点是一个动态的概念。

    后面还有后置通知,环绕通知,异常通知,引入通知

    上机练习:你把老师写的代码看看写一遍

    需求:

    在调用完Test1Service的sayHello()后,完成资源的关闭

    提问?说spring的aop中,当你通过代理对象去实现aop的时候,获取的ProxyFactoryBean是什么类型?

    答:返回的是一个代理对象,如果目标对象实现了接口,则spring使用jdk的动态代理技术完成,如果目标对象没有实现接口,则spring使用CGLIB动态代理技术完成.

    提一个问题

    Class A{

    private String name;

    public void setName(String name){

           system.out.println(“name” + name);

    }

    }

    beans.xml

    <bean id=”a” class=”A”>

        <property name=”name” value=”顺平” />

    </bean>

    理解:

    A a = new A();

    a.setName(“顺平”);

    需求:

    在进入sayhello()函数以后

    sayHello(){

    连接点

    bi.xx

    }

    需求:

    织入的通知会对所有的函数都有影响,通过引入通知来选择织入

    我们只希望在调用sayHello()来进行前置通知或后置通知的处理,我不希望我们的sayBye参与

    通过引入通知我们可以自定义切入点。

    切入点允许使用正则表达式过滤

    使用spring的静态切入点(续)

      正则表达式切入点

      RegexpMethodPointcut

    符号

    描述

    示例

    匹配

    不匹配

    .

    匹配任何单个字符

    setFoo.

    setFooB

    setFoo setFooBar

    +

    匹配前一个字符一次或多次

    setFoo.+

    setFooBar

    setFooB

    setFoo

    *

    匹配前一个字符0次或多次

    setFoo.*

    setFoo

    setFooB, setFooBar

     

    匹配任何正则表达式符号

    .setFoo.

    bar.setFoo

    setFoo

     

     

    项目结构

    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:context="http://www.springframework.org/schema/context"
    		xmlns:tx="http://www.springframework.org/schema/tx"
    		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" 
    				>
    
    <!-- 配置被代理的对象 -->
    <bean id="test1Service" class="com.litao.aop.Test1Service">
    <property name="name" value="顺平" />
    </bean>
    <!-- 配置前置通知 
    
    	proxyFactoryBean implements TestServiceInter,TestServiceInter2{
    		public void sayHello();
    	}
    	
    	思考
    	interface Inter1{};
    	class A implements Inter1,Inter2{
    	}
    	Inter1 a=new A();
    	Inter2 b=(Inter2)a;
    -->
    <!-- 配置异常通知 -->
    <bean id="myMethodBeforeAdvice" class="com.litao.aop.MyMethodBeforeAdvice" /> 
    <!-- 配置后置通知 -->
    <bean id="myAfterReturnningAdvice" class="com.litao.aop.MyAfterReturnningAdvice" />
    <!-- 配置环绕通知 -->
    <bean id="myMethodInterceptor" class="com.litao.aop.MyMethodInterceptor" />
    <!-- 配置异常通知 -->
    <bean id="myThrowsAdvice" class="com.litao.aop.MyThrowsAdvice" />
    <!-- 定义前置通知的切入点 -->
    <bean id="myMethodBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    	<property name="advice" ref="myMethodBeforeAdvice" />
    	<property name="mappedNames">
    		<list>
    			<value>sayHello</value>
    		</list>
    	</property>
    </bean>
    <!-- 配置代理对象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 代理接口集 -->
    <property name="proxyInterfaces">
    	<list>
    		<value>com.litao.aop.TestServiceInter</value>
    		<value>com.litao.aop.TestServiceInter2</value>
    	</list>
    </property>
    <!-- 把通知织入到代理对象  -->
    <property name="interceptorNames">
    	<!-- 相当于包MyMethodBeforeAdvice前置通知和代理对象关联,我们也
    	可以把通知看出拦截器,struts2核心拦截器 -->
    	<list>
    		<!-- 相当于使用自定义切入点来控制前置通知 -->
    		<value>myMethodBeforeAdviceFilter</value>
    		<!-- 织入后置通知 -->
    		<value>myAfterReturnningAdvice</value>
    		<!-- 织入环绕通知 -->
    		<value>myMethodInterceptor</value>
    		<!-- 织入异常通知 -->
    		<value>myThrowsAdvice</value>
    	</list>
    </property>
    <!-- 配置被代理对象,可以指定 -->
    <property name="target" ref="test1Service"/>
    </bean>
    </beans>
    

      App1.java

    package com.litao.aop;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class App1 {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		 ApplicationContext ac = new ClassPathXmlApplicationContext("com/litao/aop/beans.xml");
    		 TestServiceInter ts = (TestServiceInter)ac.getBean("proxyFactoryBean");
    		 System.out.println("ts 类型是什么"+ts);
    		 ts.sayHello();
    		 
    		 ((TestServiceInter2)ts).sayBye();		 
    
    	}
    
    }
    

      MyAfterReturnningAdvice.java

    package com.litao.aop;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.AfterReturningAdvice;
    
    public class MyAfterReturnningAdvice implements AfterReturningAdvice {
    
    	@Override
    	public void afterReturning(Object returnValue, Method method,
    			Object[] args, Object target) throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("关闭资源  ...");
    	}
    
    }
    

      MyMethodBeforeAdvice.java

    package com.litao.aop;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.MethodBeforeAdvice;
    
    public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    
    	/**
    	 * method:被调用的方法
    	 * args:给method传递的参数
    	 * target:目标对象
    	 */
    	public void before(Method method, Object[] args, Object target)
    			throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("*********************************");
    		System.out.println("记录日志..."+method.getName());
    	}
    
    }
    

      MyMethodInterceptor.java

    package com.litao.aop;
    
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    
    public class MyMethodInterceptor implements MethodInterceptor {
    
    	@Override
    	public Object invoke(MethodInvocation arg0) throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("调用方法前执行...");
    		Object obj = arg0.proceed();
    		System.out.println("调用方法后执行...");
    		return obj;
    	}
    
    }
    

      MyThrowsAdvice.java

    package com.litao.aop;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.ThrowsAdvice;
    
    public class MyThrowsAdvice implements ThrowsAdvice {
    	
    	public void afterThrowing(Method m,Object[] os,Object target,Exception e){
    		System.out.println("出异常了" + e.getMessage());
    	}
    
    
    }
    

      Test1Service.java

    package com.litao.aop;
    
    public class Test1Service implements TestServiceInter,TestServiceInter2 {
    
    	private String name;
    	
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void sayHello() {
    		// TODO Auto-generated method stub
    		System.out.println("hi " + name);
    	}
    
    	
    	public void sayBye() {
    		// TODO Auto-generated method stub
    		System.out.println("bye " + name);
    		//int i = 9/0;
    		
    	}
    
    }
    

      TestServiceInter.java

    package com.litao.aop;
    
    public interface TestServiceInter {
    	
    	public void sayHello();
    
    }
    

      TestServiceInter2.java

    package com.litao.aop;
    
    public interface TestServiceInter2 {
    	
    	public void sayBye();
    }
    

      

  • 相关阅读:
    文字超出省略号表示的几种方法
    Sqlserver数据库死锁
    Session丢失原因与解决方案
    CLR Profiler 性能分析工具 (转)
    微软HoloLens虚拟现实可以开发了。
    数据表分区
    SQLSERVER内核架构剖析 (转)
    理解SQL SERVER中的分区表(转)
    SQL Server Profile:使用方法和指标说明
    监视剪贴板(转)
  • 原文地址:https://www.cnblogs.com/beautiful-code/p/5790278.html
Copyright © 2011-2022 走看看