首页 > 代码库 > 关于Spring的一些笔记
关于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 = "http://www.mamicode.com/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 = "http://www.mamicode.com/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 = "http://www.mamicode.com/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
日志完成...
可以看到,在执行方法的前后,都有通知织入。
关于Spring的一些笔记