• 关于Spring的一些笔记


    1 Spring是什么?

    不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。

    具体步骤有:

    1、编写业务对象 UserDao UserService

    2、配置ApplicationContext.xml

    3、实例化Spring IOC

    4、通过IOC使用Spring加工过的业务对象

     

    以一个实例说明:

    1 package com.aop2;
    2 
    3 public interface IMessage {
    4     public void check();
    5 }
     1 package com.aop2;
     2 
     3 public class Message implements IMessage {
     4 
     5     private String name;
     6 
     7     public String getName() {
     8         return name;
     9     }
    10 
    11     public void setName(String name) {
    12         this.name = name;
    13     }
    14 
    15     public void check() {
    16         System.out.println("checking " + name);
    17     }
    18 
    19 }

    配置beans.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:p="http://www.springframework.org/schema/p"
     5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     6     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
     7 
     8     <bean id = "message" class = "com.aop2.Message">
     9         <property name = "name" value = "alvin"/>
    10     </bean>
    11 
    12 </beans>

    添加测试类:

     1 package com.aop2;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class AopTest {
     8     @Test
     9     public void test() {
    10         ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
    11                 "com/aop2/beans.xml");
    12         IMessage message1 = (IMessage)applicationContext.getBean("message");
    13         message1.check();
    14     }
    15 }

    输出:checking alvin

    2 通过代理实现

    上述过程并没有使用代理机制,下面使用Spring的动态代理机制实现:

    更改配置类:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:p="http://www.springframework.org/schema/p"
     5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     6     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
     7 
     8     <!-- 配置被代理对象 -->
     9     <bean id = "message" class = "com.aop2.Message">
    10         <property name = "name" value = "alvin"/>
    11     </bean>
    12     
    13     <!-- 配置代理对象 -->
    14     <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    15         <!-- 代理接口集 -->
    16         <property name="proxyInterfaces">
    17             <list>
    18                 <value>com.aop2.IMessage</value>
    19             </list>
    20         </property>
    21         
    22         <!-- 配置被代理对象 -->
    23         <property name="target" ref="message" />
    24     </bean>
    25 
    26 </beans>

    修改测试类:

    package com.aop2;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AopTest {
        @Test
        public void test() {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                    "com/aop2/beans.xml");
            IMessage message1 = (IMessage)applicationContext.getBean("proxyFactoryBean");
            message1.check();
        }
    }

    测试结果:checking alvin

    可以看到,测试结果并没有改变,但是我们在beans.xml配置中把被代理对象message利用IOC机制放入代理对象,实现了控制的反转,在测试类中,我们将不再直接取出message类,而是通过调用动态代理类proxyFactoryBean来调用类,并取得类方法。这就揭示了Spring的思想——解耦。它是的类与类之间的耦合度降低,我们不再类中直接调用相应的方法,而是通过bean容器配置,设置必要属性的方法来使用。

    3 调用多个接口

    增加接口:

    1 package com.aop2;
    2 
    3 public interface IMessage2 {
    4     public void release();
    5 }

    添加property:

    1 <property name="proxyInterfaces">
    2     <list>
    3         <value>com.aop2.IMessage</value>
    4         <value>com.aop2.IMessage2</value>
    5     </list>
    6 </property>

    测试类:

     1 package com.aop2;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class AopTest {
     8     @Test
     9     public void test() {
    10         ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
    11                 "com/aop2/beans.xml");
    12         IMessage message1 = (IMessage)applicationContext.getBean("proxyFactoryBean");
    13         IMessage2 message2 = (IMessage2)applicationContext.getBean("proxyFactoryBean");
    14         message1.check();
    15         message2.release();
    16     }
    17 }

    测试结果为:

    checking alvin
    release alvin

    4 AOP

    AOP是在动态代理的基础上实现的,利用InvocationHandler动态代理接口产生一个对象的代理对象,对被代理对象进行代理,以下是动态代理的实质:

     1 public class DaiLi_DongTai {
     2     public static void main(String[] args) {
     3         IGamePlayer player = new GamePlayer("张三");
     4         InvocationHandler handler = new GamePlayIG(player);
     5         System.out.println("开始时间:" + new Date());
     6         ClassLoader cl = player.getClass().getClassLoader();
     7         IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl,
     8                 new Class[] { IGamePlayer.class }, handler);
     9         proxy.login("zhagnsan", "password");
    10         proxy.killBoss();
    11         proxy.upgrade();
    12         System.out.println("结束时间:" + new Date());
    13     }
    14 }
    15 
    16 class GamePlayIG implements InvocationHandler {
    17     Class cls = null; //被代理者
    18     Object obj = null; //被代理的实例
    19     public GamePlayIG(Object obj) {//我要代理谁
    20         this.obj = obj;
    21     }
    22     //调用被代理的方法
    23     public Object invoke(Object proxy, Method method, Object[] args)
    24             throws Throwable {
    25         Object result = method.invoke(this.obj, args);
    26         return result;
    27     }
    28 }

    5 AOP实现

    加入AOP编程,这里以环绕通知为例,在方法执行的前后加入日志程序。

    设定MyMethodInterceptor类:

     1 package com.aop2;
     2 
     3 import org.aopalliance.intercept.MethodInterceptor;
     4 import org.aopalliance.intercept.MethodInvocation;
     5 
     6 public class MyMethodInterceptor implements MethodInterceptor{
     7 
     8     public Object invoke(MethodInvocation arg0) throws Throwable {
     9         System.out.println("写入日志...");
    10         Object object = arg0.proceed();
    11         System.out.println("日志完成...");
    12         return object;
    13     }
    14 }

    修改beans.xml配置:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:p="http://www.springframework.org/schema/p"
     5     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     6     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
     7 
     8     <!-- 配置被代理对象 -->
     9     <bean id = "message" class = "com.aop2.Message">
    10         <property name = "name" value = "alvin"/>
    11     </bean>
    12     
    13     <!-- 配置环绕通知 -->
    14     <bean id = "myMethodInterceptor" class = "com.aop2.MyMethodInterceptor"/>
    15     
    16     <!-- 配置代理对象 -->
    17     <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    18         <!-- 代理接口集 -->
    19         <property name="proxyInterfaces">
    20             <list>
    21                 <value>com.aop2.IMessage</value>
    22                 <value>com.aop2.IMessage2</value>
    23             </list>
    24         </property>
    25         
    26         <!-- 织入通知对象 -->
    27         <property name = "interceptorNames">
    28             <list>
    29                 <value>myMethodInterceptor</value>
    30             </list>
    31         </property>
    32         
    33         <!-- 配置被代理对象 -->
    34         <property name="target" ref="message" />
    35     </bean>
    36 
    37 </beans>

    输出为:

    写入日志...
    checking alvin
    日志完成...
    写入日志...
    release alvin
    日志完成...

    可以看到,在执行方法的前后,都有通知织入。

     

  • 相关阅读:
    PyCharm小技巧
    How to install torcs package in Debian
    QT4.8.6静态编译
    Debian初识(选择最佳镜像发布站点加入source.list文件)
    Dev-C++ 小问题锦集
    ubuntu 12.04lts 安装mysql ,并通过QT连接
    win7下安装ubuntu14.04lts 双系统
    cmake打印变量值
    驾车常识:小轿车灯光
    汽车点火开关的功能介绍
  • 原文地址:https://www.cnblogs.com/cityflickr/p/4004429.html
Copyright © 2020-2023  润新知