查看完整版本: [-- Spring 基础教程(三) --]

风信Java论坛 ›› Spring 讨论专区 ›› Spring 基础教程(三) 登录 -> 注册

1F Spring 基础教程(三)   唧唧 Post by : 2008-07-23 02:02:21.0

属性编辑器: PropertyEditorSupport
作用:如果一个类中的属性为Date类型,那么在beans.xml中设置的Date值不能与Date匹配,那么我们需要对beans.xml中的属性进行编辑,让它转化为Date类型的
CustomEditorConfigurer可以读取实现java.beans.PropertyEditor接口的类,将字符串转为指定的类型,更方便的使用PropertyEditorSupport.PropertyEditorSupport实现PropertyEditor,必须重新定义setAsText
程序目标:如果bean类中有不是一般类型的属性的话,并且在xml文件中有这个属性的赋值,那么可以使用属性编辑器对属性进行类型的封装,然后通过org.springframework.beans.factory.config.CustomEditorConfigurer类在xml中与属性编辑器处理类绑定
接口:
package yuchen.dataeditor;
 
public interface A {
     public void display();
}
 
实现类:
package yuchen.dataeditor;
 
import java.util.Date;
 
public class AImp implements A {
 
     private Date date;
     public void display() {
         // TODO Auto-generated method stub
         if(date instanceof Date){
              System.out.println(date);
         }
        
     }
     public Date getDate() {
         return date;
     }
     public void setDate(Date date) {
         this.date = date;
     }
    
}
 
属性编辑器类
package yuchen.dataeditor;
 
import java.beans.PropertyEditorSupport;//属性编辑器
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
 
public class DateEditor extends PropertyEditorSupport {
 
     private Date date;
     @Override
     public void setAsText(String str) throws IllegalArgumentException {
         // TODO Auto-generated method stub
         String[] a=str.split("/");
         int year = Integer.parseInt(a[0]);
         int month = Integer.parseInt(a[1]);
         int day = Integer.parseInt(a[2]);
         Calendar cal= new GregorianCalendar(year,month-1,day);
         date = cal.getTime();
     }
 
     @Override
     public Object getValue() {
         // TODO Auto-generated method stub
         return date;
     }
    
}
 
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="a" class="yuchen.dataeditor.AImp">
         <property name="date">
              <value>1998/07/07</value>
         </property>
     </bean>
    
     <bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
         <property name="customEditors">
              <map>
                   <entry key="java.util.Date">
                       <bean
class="yuchen.dataeditor.DateEditor"/>
                   </entry>
              </map>
         </property>
     </bean>
</beans>
 
Test:
package yuchen.dataeditor;
/*
 * 属性编辑器:java.beans.PropertyEditorSupport
 * 如何知道属性编辑器类为谁服务呢?
 * <bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
         <property name="customEditors">
              <map>
                   <entry key="java.util.Date">
                       <bean
class="yuchen.dataeditor.DateEditor"/>
                   </entry>
              </map>
         </property>
     </bean>
 */
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/dataeditor/beans.xml");
         A aa=(A) context.getBean("a");
         aa.display();
     }
 
}
 
属性设置器:
除了通过beans.xml设置属性以外,还可以通过PropertyPlaceholderConfigurer为bean属性设置值,它利用属性文件
程序目标:测试PropertyPlaceholderConfigurer类
 
接口:
package yuchen.propertyphc;
 
public interface A {
     public void display();
}
 
实现类:
package yuchen.propertyphc;
 
import java.util.Date;
 
public class AImp implements A {
 
     private Date date;
     public void display() {
         // TODO Auto-generated method stub
         if(date instanceof Date){
              System.out.println(date);
         }
        
     }
     public Date getDate() {
         return date;
     }
     public void setDate(Date date) {
         this.date = date;
     }
    
}
 
属性编辑器:
package yuchen.propertyphc;
 
import java.beans.PropertyEditorSupport;//属性编辑器
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
 
public class DateEditor extends PropertyEditorSupport {
 
     private Date date;
     @Override
     public void setAsText(String str) throws IllegalArgumentException {
         // TODO Auto-generated method stub
         String[] a=str.split("/");
         int year = Integer.parseInt(a[0]);
         int month = Integer.parseInt(a[1]);
         int day = Integer.parseInt(a[2]);
         Calendar cal= new GregorianCalendar(year,month-1,day);
         date = cal.getTime();
     }
 
     @Override
     public Object getValue() {
         // TODO Auto-generated method stub
         return date;
     }
    
}
 
属性文件:
date=2001/10/3
 
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="a" class="yuchen.propertyphc.AImp">
         <property name="date">
              <value>${date}</value>
         </property>
     </bean>
    
     <bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
         <property name="customEditors">
              <map>
                   <entry key="java.util.Date">
                       <bean
class="yuchen.propertyphc.DateEditor"/>
                   </entry>
              </map>
         </property>
     </bean>
    
     <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigur
er">
         <property name="locations">
              <list>
                  
<value>yuchen/propertyphc/AImp.properties</value>
              </list>
         </property>
     </bean>
 
</beans>
 
Test:
package yuchen.propertyphc;
/*
 * 属性设置器:
 * 通过属性文件给bean的属性设置值
 * 在beans.xml中添加属性设置器类:
 * <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigur
er">
         <property name="locations">
              <list>
                  
<value>yuchen/propertyphc/AImp.properties</value>
              </list>
         </property>
     </bean>
     属性文件:
     date=2001/10/3
 */
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/propertyphc/beans.xml");
         A aa=(A) context.getBean("a");
         aa.display();
     }
 
}
 
属性覆盖器:
作用:属性文件中设置好的属性值将会覆盖掉beans.xml中类属性值
接口:
package yuchen.propertypoc;
 
public interface A {
     public void display();
}
 
实现类:
package yuchen.propertypoc;
 
import java.util.Date;
 
public class AImp implements A {
 
     private String name;
     public void display() {
         // TODO Auto-generated method stub
         System.out.println(this.name);
        
     }
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this.name = name;
     }
    
    
}
 
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="a" class="yuchen.propertypoc.AImp">
         <property name="name">
              <value>zhao</value>
         </property>
     </bean>
    
     <bean
class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
>
         <property name="location">
              <value>yuchen/propertypoc/AImp.properties</value>
         </property>
     </bean>
 
</beans>
 
属性文件:
a.name=yuchen
 
Test:
package yuchen.propertypoc;
/*
 * 覆盖:
 * 使用PropertyOverrideConfigurer那么属性文件中设置的属性值
 * 会覆盖在beans.xml 的bean类中设置的属性值
 */
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/propertypoc/beans.xml");
         A aa=(A) context.getBean("a");
         aa.display();
     }
 
}
 
ApplicationContext的事件特性(观察者模式):
1.ApplicationContext发布事务
2.事件响应者需要实现ApplicationListener
3.定义一个事件类,继承ApplicationEvent
接口:
package yuchen.event;
 
public interface Model {
     public String superDate();
     public void update();
}
 
接口:
package yuchen.event;
 
public interface View {
     public void display();
}
 
实现类:
package yuchen.event;
 
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
 
public class ModelImpl implements Model,ApplicationContextAware{
 
     private String name;
     private ApplicationContext context;
     public String superDate() {
         // TODO Auto-generated method stub
         return name;
     }
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this.name = name;
     }
     public void update(){
         this.setName("zhang");
         if(context!=null){
              context.publishEvent(new RefreshEvent(this,"update
()"));
         }else{
              System.out.println("null");
         }
 
     }
     public void setApplicationContext(ApplicationContext arg0) throws
BeansException {
         // TODO Auto-generated method stub
         context=arg0;
     }
}
 
实现类:
package yuchen.event;
 
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
 
public class ViewImpl implements View,ApplicationListener{
     private Model model;
     public void display() {
         // TODO Auto-generated method stub
         String rst=model.superDate();
         System.out.println(rst);
     }
     public Model getModel() {
         return model;
     }
     public void setModel(Model model) {
         this.model = model;
     }
     public void onApplicationEvent(ApplicationEvent arg0) {
         // TODO Auto-generated method stub
         if(arg0 instanceof RefreshEvent){
         System.out.println("事件发生后调用onApplicationEvent方法");
         this.display();
         }
     }
    
}
 
事件类:
package yuchen.event;
 
import org.springframework.context.ApplicationEvent;
 
public class RefreshEvent extends ApplicationEvent{
     private String message;
     public RefreshEvent(Object arg0,String message) {
         super(arg0);
         this.message=message;
         // TODO Auto-generated constructor stub
     }
     public String getMessage() {
         return message;
     }
     public void setMessage(String message) {
         this.message = message;
     }
    
}
 
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="model" class="yuchen.event.ModelImpl">
         <property name="name">
              <value>yuchen</value>
         </property>
     </bean>
    
     <bean id="view" class="yuchen.event.ViewImpl">
         <property name="model">
              <ref bean="model"></ref>
         </property>
     </bean>
</beans>
 
Test:
package yuchen.event;
/*
 * 程序目标:当更新model里的name时,context发布事件,再次调用display方法
 * ApplicationContext用来发布事件
 * ApplicationEvent为事件的抽象类,需要继承此类声明一个事件对象
 * ApplicationListener监听器监听是否有事件发生,当context发布事件
 * 后,会调用实现了此接口的bean中的onApplicationEvent()方法
 * 实现ApplicationContextAware的类可获得context
 */
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/event/beans.xml");
         View v=(View) context.getBean("view");
         v.display();
         System.out.println("----------------");
         ModelImpl m=(ModelImpl)context.getBean("model");
         m.update();
     }
 
}
 
国际化:
ApplicationContext的getMessage方法可以做国际化
并且在beans.xml中需要配置国际化文件的路径
 
修改上面的类:将消息的内容国际化
ModelImpl.java:
public void update(){
         this.setName("zhang");
         if(context!=null){
              //context.publishEvent(new RefreshEvent(this,"update()"));
              context.publishEvent(new RefreshEvent(this,context.getMessage("message", new String[]{"message","!!!!!"}, Locale.CHINA)));
         }else{
              System.out.println("null");
         }
 
     }
 
加入国际化属性文件:
message_zh.properties:
message = {0} \u5237\u65b0 {1}
 
Message_en.properties:
message = {0} refresh{1}
 
修改beans.xml:
加入:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
         <property name="basenames">
              <list>
                   <value>yuchen/event/message</value>
              </list>
         </property>
     </bean>
 
工厂bean:
以前的程序都是通过容器产生工厂,容器的表现有两种
1.XmlBeanFactory
2.ApplicationContext
现在不用得到工厂,通过一个工厂bean去得到bean实例
产生的实例为工厂bean创建的产品,并不是工厂对象
 
package yuchen.factorybean;
 
import java.util.Properties;
 
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
Test:
public class Test {
 
     /**
      * @param args
      * @throws Exception
      */
     public static void main(String[] args) throws Exception {
         ApplicationContext factory = new
ClassPathXmlApplicationContext("yuchen/factorybean/beans.xml");
         long s = (Long)factory.getBean("a");
        
         System.out.println(s);
        
        
        
         String classpath = (String)factory.getBean("classpath");
         System.out.println(classpath);
        
         FactoryBean o =(FactoryBean)factory.getBean("&classpath");
         String classpath2 = (String)o.getObject();
         System.out.println(classpath2);
     }
 
}
 
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="a"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property
name="targetClass"><value>java.lang.System</value></property>
   <property
name="targetMethod"><value>currentTimeMillis</value></property>    
     </bean>
 
    
     <bean id="props"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property name="targetClass"
value="java.lang.System"></property>
         <property name="targetMethod" value="getProperties"/>
     </bean>
 
    
     <bean id="classpath"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property name="targetObject"><ref
local="props"/></property>
         <property name="targetMethod"
value="getProperty"></property>
         <property name="arguments">
              <value>java.class.path</value>
         </property>
     </bean>
    
</beans>
 
面向方面编程AOP:
1.什么是面向方面编程?有什么用?
2.一个陈旧的案例
3.AOP的一些概念
4.第一个AOP程序
5.前置Advice
6.后置Advice
7.环绕Advice
8.异常抛出Advice
 
什么是面向方面编程?有什么用?
面向方面编程就是就是将类中掺杂的与业务无关的代码抽象出来,以便重用
作用:重用,解耦合
 
包含两个要素:
1.在哪里加入服务(方法前?方法后?属性?)
2.具体为哪个类的哪个方法或属性加入服务
 
例如:
1.要在方法前加入事务服务
2.为A类的sayhello()业务方法加入服务
两者组合就是一个方面
 
一个陈旧的案例:
程序目标:为A类的业务方法1加入事务和安全的服务,为业务方法2只加入事务的服务
package yuchen.aop.oldcase;
 
public class OldCase {
    
     public void execute1(){
         safetybackcheck();
         System.out.println("事务开始代码");
         this.operation1();
         System.out.println("事务结束代码");
     }
    
     public void execute2(){
         System.out.println("事务开始代码");
         this.operation2();
         System.out.println("事务结束代码");
     }
 
     public void safetybackcheck(){
         System.out.println("安全检查代码");
     }
    
     public void operation1(){
         System.out.println("业务代码1");
     }
    
     public void operation2(){
         System.out.println("业务代码2");
     }
}
 
发现问题:业务代码和服务代码互相掺杂,结构不清晰,维护代码不方便,也不方便重用
那么使用AOP编程就是为了解决这个问题
 
AOP的一些概念:
关注点:业务核心代码(如: operation1)和系统服务代码(事务,安全代码)都是关注点
横切关注点:程序中的系统服务代码都是横切关注点
核心关注点:就是业务核心代码
方面(aspect):advice+pointcut=aspect,一个方面说明了为哪些类的哪些方法,属性等加入哪些服务,例如:为A类的a()方法加入事务,安全服务,这就是方面
advice: 在哪里加入服务(方法前?方法后?属性?),就是拦截器
pointcut: 具体为哪个类的哪个方法或属性加入服务
连接点:能插入服务的位置是连接点:如:方法,属性,异常抛出,Spring Aop只支持一种类型的连接点(方法)
织入(weaving):就是将方面加入到具体的哪个对象中
Aop代理:Aop Proxy:代理对象,他去调用被包装了服务的业务方法
AOP的目标就是要将横切关注点与核心关注点分离,实现解耦合,重用这些服务
 
第一个AOP程序:
接口:
package yuchen.aop.firstaop;
 
public interface Business {
     public void business1();
     public void business2();
}
 
核心业务类:
package yuchen.aop.firstaop;
 
public class BusinessImpl implements Business {
 
     public void busMethod1(){
         this.business1();
     }
     public void busMethod2(){
         this.business2();
     }
     public void business1() {
         // TODO Auto-generated method stub
         System.out.println("核心业务方法1");
     }
 
     public void business2() {
         // TODO Auto-generated method stub
         System.out.println("核心业务方法2");
     }
 
}
 
安全服务:
package yuchen.aop.firstaop;
 
import java.lang.reflect.Method;
 
import org.springframework.aop.MethodBeforeAdvice;
 
public class SecuityBeforeAdvice implements MethodBeforeAdvice{
 
     public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
         // TODO Auto-generated method stub
         this.check();
     }
    
     public void check(){
         System.out.println("安全检查");
     }
}
 
事务服务:
package yuchen.aop.firstaop;
 
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
 
public class AffairAroundAdvice implements MethodInterceptor{
 
     public Object invoke(MethodInvocation arg0) throws Throwable {
         // TODO Auto-generated method stub
         this.transactionStart();
         Object object=arg0.proceed();
         this.transactionEnd();
         return object;
     }
 
     public void transactionStart(){
         System.out.println("事务开始");
     }
    
     public void transactionEnd(){
         System.out.println("事务结束");
     }
}
 
事务服务pointcut:
package yuchen.aop.firstaop;
 
import java.lang.reflect.Method;
 
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
 
public class PointcutImpl extends StaticMethodMatcherPointcut{
 
     public boolean matches(Method arg0, Class arg1) {
         // TODO Auto-generated method stub
         if(arg0.getName().equals("business1")){
              return true;
         }
         return false;
     }
 
     @Override
     public ClassFilter getClassFilter() {
         // TODO Auto-generated method stub
         return new ClassFilter(){
 
              public boolean matches(Class arg0) {
                   // TODO Auto-generated method stub
                   return (arg0==BusinessImpl.class);
              }
             
         };
     }
    
}
 
Test:
package yuchen.aop.firstaop;
/*
 * 为类中的某些方法加上事务和安全
 */
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ProxyFactory pf=new ProxyFactory();
         Business bi=new BusinessImpl();
         SecuityBeforeAdvice sb=new SecuityBeforeAdvice();
         Pointcut p=new PointcutImpl();
         Advisor advisor=new DefaultPointcutAdvisor(p,sb);
         AffairAroundAdvice ad=new AffairAroundAdvice();
         pf.addAdvisor(advisor);
         pf.addAdvice(ad);
         pf.setTarget(bi);
         Business b=(Business) pf.getProxy();
         b.business1();
         b.business2();
     }
 
}
开发步骤:
1.写核心业务类
2.写系统服务类(advice)
3.选择性的写过滤类(pointcut)
4.写客户代码:通过DefaultPointcutAdvisor将advice and pointcut组装,代理工厂添加advice,设置目标对象,生成代理对象,代理对象调用业务方法
 
使用proxyfactorybean方式:
添加配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="businessimpl" class="yuchen.aop.updatefirstaop.BusinessImpl">
        
     </bean>
    
     <bean id="secuity" class="yuchen.aop.updatefirstaop.SecuityBeforeAdvice">
        
     </bean>
    
     <bean id="affair" class="yuchen.aop.updatefirstaop.AffairAroundAdvice">
        
     </bean>
    
     <bean id="pointcutimpl" class="yuchen.aop.updatefirstaop.PointcutImpl">
        
     </bean>
    
     <bean id="befadvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
         <property name="advice">
              <ref local="secuity"></ref>
         </property>
         <property name="pointcut">
              <ref local="pointcutimpl"></ref>
         </property>
     </bean>
    
     <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target">
              <ref bean="businessimpl"></ref>
         </property>
        
         <property name="interceptorNames">
              <list>
                   <value>befadvisor</value>
                   <value>affair</value>
              </list>
         </property>
     </bean>
</beans>
 
 
修改Test:
package yuchen.aop.updatefirstaop;
 
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/updatefirstaop/beans.xml");
         Business b=(Business) context.getBean("factory");
         b.busMethod1();
     }
 
}
前置Advice:
接口:
package yuchen.aop.before.proxyfactory;
 
public interface Business {
     public void busMethod1();
     public void busMethod2();
}
 
 
核心业务实现类:
package yuchen.aop.before.proxyfactory;
 
public class BusinessImpl implements Business {
 
     public void busMethod1(){
         this.business1();
     }
     public void busMethod2(){
         this.business2();
     }
     public void business1() {
         // TODO Auto-generated method stub
         System.out.println("核心业务方法1");
     }
 
     public void business2() {
         // TODO Auto-generated method stub
         System.out.println("核心业务方法2");
     }
 
}
 
实体类:
package yuchen.aop.before.proxyfactory;
 
public class UserInfo {
     private String username;
     private String password;
    
     public UserInfo() {
         super();
     }
    
     public UserInfo(String username, String password) {
         super();
         this.username = username;
         this.password = password;
     }
 
     public String getPassword() {
         return password;
     }
     public void setPassword(String password) {
          this.password = password;
     }
     public String getUsername() {
         return username;
     }
     public void setUsername(String username) {
         this.username = username;
     }
    
}
 
 
用户登陆管理类:
package yuchen.aop.before.proxyfactory;
 
public class UserMagager {
     private static ThreadLocal t=new ThreadLocal();
     public static void login(String username,String password){
         t.set(new UserInfo(username,password));
     }
     public static void logout(){
         t.set(null);
     }
     public static UserInfo getUserInfo(){
         return (UserInfo)t.get();
     }
     public static void validate(){
         UserInfo user=getUserInfo();
         if(user==null){
              throw new UserInfoException("您还没有登陆");
         }else if(user.getUsername().equals("admin")){
              System.out.println("系统管理员登陆");
         }else{
              throw new UserInfoException("您不是系统管理员");
         }
     }
}
 
自定义异常:
package yuchen.aop.before.proxyfactory;
 
public class UserInfoException extends RuntimeException {
     public UserInfoException(String msg){
         super(msg);
     }
}
 
 
前置advice:
package yuchen.aop.before.proxyfactory;
 
import java.lang.reflect.Method;
 
import org.springframework.aop.MethodBeforeAdvice;
 
public class SecuityBeforeAdvice implements MethodBeforeAdvice{
 
     public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
         // TODO Auto-generated method stub
         UserMagager.validate();
     }
    
}
 
Test:
package yuchen.aop.before.proxyfactory;
/*
 * 当抛出异常的时候,拦截器中断
 */
import org.springframework.aop.framework.ProxyFactory;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         Business bi=getProxyFactory();
         try{
              bi.busMethod1();
         }catch(UserInfoException ue){
              System.out.println(ue.getMessage());
         }
         UserMagager.login("admin", "1234");
         bi.busMethod1();
         UserMagager.logout();
        
         UserMagager.login("yuchen", "123");
         try{
              bi.busMethod1();
         }catch(UserInfoException ue){
              System.out.println(ue.getMessage());
         }
        
     }
    
     public static Business getProxyFactory(){
         ProxyFactory pf=new ProxyFactory();
         Business business=new BusinessImpl();
         SecuityBeforeAdvice sa=new SecuityBeforeAdvice();
         pf.setTarget(business);
         pf.addAdvice(sa);
         return (Business)pf.getProxy();
     }
}
 
 
采用声明服务方式:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="businessimpl" class="yuchen.aop.before.proxyfactorybean.BusinessImpl">
        
     </bean>
    
     <bean id="secuity" class="yuchen.aop.before.proxyfactorybean.SecuityBeforeAdvice">
        
     </bean>
    
     <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target">
              <ref bean="businessimpl"></ref>
         </property>
        
         <property name="interceptorNames">
              <list>
                   <value>secuity</value>
              </list>
         </property>
     </bean>
</beans>
 
修改Test:
package yuchen.aop.before.proxyfactorybean;
/*
 * 当抛出异常的时候,拦截器中断
 */
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/before/proxyfactorybean/beans.xml");
         Business business=(Business) context.getBean("factory");
        
         UserMagager.login("admin", "123");
         business.busMethod1();
         business.busMethod2();
         UserMagager.logout();
        
         UserMagager.login("yuchen", "1");
         try{
              business.busMethod1();
         }catch(UserInfoException ue){
              System.out.println(ue.getMessage());
         }
         UserMagager.logout();
        
         try{
              business.busMethod1();
         }catch(UserInfoException ue){
              System.out.println(ue.getMessage());
         }
        
     }
    
}
 
后置Advice:
实体类:
package yuchen.aop.after.proxyfactory;
/*
 * 业务类
 */
public class Man {
     private String name;
     private int age;
    
     public Man() {
         super();
     }
 
     public Man(String name, int age) {
         super();
         this.name = name;
         this.age = age;
     }
 
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
    
     public Man growup(){
         ++age;
         return this;
     }
}
 
核心业务类:
package yuchen.aop.after.proxyfactory;
/**
 * 服务:方法计数器
 */
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
 
public class Counter {
     private static Map countmap=new HashMap();//存方法名和调用次数
 
     public Map getCountmap() {
         return countmap;
     }
 
     public void setCountmap(Map countmap) {
         this.countmap = countmap;
     }
    
     public void count(Method method){
         count(method.getName());
     }
    
     //计算方法调用的次数并保存到一个map表中
     public void count(String name){
         Integer i=(Integer) countmap.get("name");
         if(i!=null){
              countmap.put(name, new Integer(i.intValue()+1));
         }else{
              countmap.put(name, 1);
         }
     }
     //返回方法调用的次数
     public int getCount(String name){
         int x;
         Integer i=(Integer) countmap.get(name);
         if(i==null){
              x=0;
         }else{
              x=i.intValue();
         }
         return x;
     }
    
}   
 
后置advice:
package yuchen.aop.after.proxyfactory;
 
import java.lang.reflect.Method;
 
import org.springframework.aop.AfterReturningAdvice;
 
public class CountAgeAfterAdvice extends Counter implements AfterReturningAdvice{
 
     public void afterReturning(Object returnvalue, Method method, Object[] parameter, Object target) throws Throwable {
         // TODO Auto-generated method stub
         //returnvalue:被拦截的方法的返回值
         //method:被拦截的方法
         //parameter:被拦截的方法的参数
         //target:被拦截的目标对象
         this.count(method);//被拦截的对象的方法调用后执行
        
         if(method.getName().equals("growup")){
              Man man=(Man)returnvalue;
              System.out.println(man.getName()+":"+man.getAge());
              System.out.println(this.getCount(method.getName()));
         }
        
     }
 
}
 
Test:
package yuchen.aop.after.proxyfactory;
 
import org.aopalliance.aop.Advice;
import org.springframework.aop.framework.ProxyFactory;
 
public class Test {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         Man man=new Man("yuchen",24);
         CountAgeAfterAdvice counter=new CountAgeAfterAdvice();
         ProxyFactory pf=new ProxyFactory();
         pf.addAdvice(counter);
         pf.setTarget(man);
         Man m=(Man) pf.getProxy();
        
         m.growup();
        
     }
 
}
 
声明式:xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="man" class="yuchen.aop.after.proxyfactorybean.Man">
         <property name="name">
              <value>yuchen</value>
         </property>
         <property name="age">
              <value>24</value>
         </property>
     </bean>
    
     <bean id="counterage" class="yuchen.aop.after.proxyfactorybean.CountAgeAfterAdvice">
        
     </bean>
    
     <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target">
              <ref bean="man"></ref>
         </property>
        
         <property name="interceptorNames">
              <list>
                   <value>counterage</value>
              </list>
         </property>
     </bean>
</beans>
 
修改Test:
package yuchen.aop.after.proxyfactorybean;
 
import org.aopalliance.aop.Advice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/after/proxyfactorybean/beans.xml");
         Man man=(Man) context.getBean("factory");
         System.out.println(man.getName()+":"+man.getAge());
         man.growup();
     }
 
}
 
环绕Advice:
业务核心类:
package yuchen.aop.interception.proxyfactory;
 
public class AccountWork {
     public void account(int num){
         for(int i=0;i<num;i++){
              work();
         }   
     }
    
     public void work(){
         System.out.println("工作中....");
     }
}
 
环绕advice:
package yuchen.aop.interception.proxyfactory;
 
import java.lang.reflect.Method;
 
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;
 
public class AccountCapabilityAdvice implements MethodInterceptor{
 
     public Object invoke(MethodInvocation invocation) throws Throwable {
         // TODO Auto-generated method stub
         StopWatch sw=new StopWatch();
         sw.start(invocation.getMethod().getName());
         Object obj=invocation.proceed();
         sw.stop();
         this.displaybulletin(invocation, sw.getTotalTimeMillis());
         return obj;
     }
    
     private void displaybulletin(MethodInvocation invocation,long l){
         Method m=invocation.getMethod();
         Object obj=invocation.getThis();
         Object[] arg=invocation.getArguments();
         System.out.println("目标类:"+obj.getClass().getName());
         System.out.println("方法:"+m.getName());
         System.out.print("方法参数:");
         for(int i=0;i<arg.length;i++){
              System.out.print(arg[i]);
              if(i!=arg.length-1){
                   System.out.println(",");
              }else{
                   System.out.println(".");
              }
         }
         System.out.println("性能测试时间:"+l);
     }
}
 
Test:
package yuchen.aop.interception.proxyfactory;
 
import org.springframework.aop.framework.ProxyFactory;
 
public class Test {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         AccountWork aa=getproxyfactory();
         aa.account(100);
     }
 
     private static AccountWork getproxyfactory(){
         ProxyFactory pf=new ProxyFactory();
         AccountWork aw=new AccountWork();
         AccountCapabilityAdvice aca=new AccountCapabilityAdvice();
         pf.setTarget(aw);
         pf.addAdvice(aca);
         return (AccountWork)pf.getProxy();
         }
}
 
声明方式:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="account" class="yuchen.aop.interception.proxyfactorybean.AccountWork">
     </bean>
    
     <bean id="acadvice" class="yuchen.aop.interception.proxyfactorybean.AccountCapabilityAdvice">
        
     </bean>
    
     <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target">
              <ref bean="account"></ref>
         </property>
        
         <property name="interceptorNames">
              <list>
                   <value>acadvice</value>
              </list>
         </property>
     </bean>
</beans>
 
修改Test:
package yuchen.aop.interception.proxyfactorybean;
 
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/interception/proxyfactorybean/beans.xml");
         AccountWork aw=(AccountWork) context.getBean("factory");
         aw.account(100);
     }
}
 
异常抛出Advice:
业务核心类:
package yuchen.aop.exception.proxyfactory;
 
import java.rmi.RemoteException;
 
public class ExceptionBean {
     public void exception1() throws RemoteException{
         throw new RemoteException("远程方法调用异常");
     }
}
 
异常抛出advice:
package yuchen.aop.exception.proxyfactory;
 
import java.lang.reflect.Method;
import java.rmi.RemoteException;
 
import org.springframework.aop.ThrowsAdvice;
 
public class ExceptionAdvice implements ThrowsAdvice{
     public void afterThrowing(Method method,Object[] args,Object target,RemoteException re){
         System.out.println("抛出异常的方法名:"+method);
         System.out.println("目标对象:"+target.getClass().getName());
         System.out.println("异常信息:"+re.getMessage());
     }
}
 
Test:
package yuchen.aop.exception.proxyfactory;
 
import java.rmi.RemoteException;
 
import org.springframework.aop.framework.ProxyFactory;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ExceptionBean bean=getProxyFactory();
         try {
              bean.exception1();
         } catch (RemoteException e) {
              // TODO Auto-generated catch block
         }
     }
     public static ExceptionBean getProxyFactory(){
         ProxyFactory pf=new ProxyFactory();
         ExceptionBean eb=new ExceptionBean();
         ExceptionAdvice ea=new ExceptionAdvice();
         pf.setTarget(eb);
         pf.addAdvice(ea);
         return (ExceptionBean)pf.getProxy();
     }
}
 
声明式方式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
     <bean id="bean" class="yuchen.aop.exception.proxyfactorybean.ExceptionBean">
        
     </bean>
    
     <bean id="advice" class="yuchen.aop.exception.proxyfactorybean.ExceptionAdvice">
        
     </bean>
    
     <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target">
              <ref bean="bean"></ref>
         </property>
        
         <property name="interceptorNames">
              <list>
                   <value>advice</value>
              </list>
         </property>
     </bean>
</beans>
 
修改Test:
package yuchen.aop.exception.proxyfactorybean;
 
import java.rmi.RemoteException;
 
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
     /**
      * @param args
      */
     public static void main(String[] args) {
         // TODO Auto-generated method stub
         ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/exception/proxyfactorybean/beans.xml");
         ExceptionBean bean=(ExceptionBean) context.getBean("factory");
         try {
              bean.exception1();
         } catch (RemoteException e) {
              // TODO Auto-generated catch block
         }
     }
}
 


风信Java论坛 ›› Spring 讨论专区 ›› Spring 基础教程(三) 登录 -> 注册

查看完整版本: [-- Spring 基础教程(三) --]
CopyRight © 2008-2009 JavaWind.Net Studio All Rights Reserved
Powered By JWind.BBS Vesion 1.0.0 Beta1 Processed in 15 ms,0 (Queries)  Gzip enabled
粤ICP备07511478号