spring 特殊bean详解

        Spring的第二讲

所学知识点:

1.使用spring的特殊bean

1.   》分散配置

2.   》定制属性编译器

2.代理

1.Jdk动态代理

2.cglib代理

3.面向切面  

 

内容:

1.   使用spring的特殊bean

1》      分散配置:

使用占位符变量代替bean装配文件中的硬编码配置。占位符采用${variable}形式。

<bean id="personServiceBean" class="cn.csdn.spring.PersonServiceBean">

      <!-- 分散配置-->

<property name="name"><value>${name}</value></property>

</bean>

<!--  分散解析的处理方法-->

第一种方式:

 <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

    <property name="location">

         <value>person.properties</value>

      </property>

<property name="locations">

<list>

         <value>person.properties</value>

</list>

    </property>

 </bean>

 

第二种方法:

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:context="http://www.springframework.org/schema/context"

       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-2.5.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

   <context:property-placeholder location="person.properties"/>

</bean>

 

2.   》定制属性编译器

  <property name="homeAddress">

             <bean class="cn.csdn.spring.Address">

                 <property name="province">

                    <value>北京</value>

                 </property>

                 <property name="city">

                    <value>北京市</value>

                 </property>

                 <property name="street">

                    <value>海淀区056街道</value>

                 </property>

                 <property name="zipCode">

                    <value>111111</value>

                 </property>

            </bean>

     

     

      </property>

      <property name="comAddress">

         <value>河北省.邢台市.宁晋县.水榭花都302</value>

     

      </property>

<!-- 定制编辑器后处理类 -->

     

      <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">

      <property name="customEditors">

         <map>

             <!-- key指向的是:需要转换的类 -->

             <entry key="cn.csdn.spring.Address">

                   <!-- value指向的是实现的编辑器类 -->

                  <bean class="cn.csdn.spring.AddressEditor"/>

             </entry>

         </map>

      </property>

  </bean>

//继承java.bean的类

publicclass AddressEditor extends PropertyEditorSupport{

 

    @Override

    publicvoid setAsText(String text) throws IllegalArgumentException {

      //java实现转换

       if(!"".equals(text)||text!=null){

           String arg[]=text.split("\\.");

           if(arg.length>3){

               Address address = new Address();

             address.setProvince(arg[0]);

             address.setCity(arg[1]);

             address.setStreet(arg[2]);

             address.setZipCode(arg[3]);

                 setValue(address);

             

           }else{

              this.setAsText(null);

           }

          

          

       }else{

          

           this.setAsText(null);

       }

    }

   

   

   

}

2.代理

1.Jdk动态代理

    package cn.csdn.srrvice;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

public class JDKProxy implements InvocationHandler{

 

     //代理的目标对象

     //private PersonServiceBean personServiceBean;

     private Object targerService;

     //根据目标对象创建代理对象

     public Object creatPoxy( Object targerService){

           

            this.targerService=targerService;

            //调用代理

            return Proxy.newProxyInstance(targerService.getClass().getClassLoader(), targerService.getClass().getInterfaces(), this);

     }

    

     /*

      * proxy 代理对象

      * methed 代理方法

      *  args   参数值

      * (non-Javadoc)

      * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])

      */

     @Override

     public Object invoke(Object proxy, Method method, Object[] args)

                   throws Throwable {

            // TODO Auto-generated method stub

            System.out.println("代理类的名称"+proxy.getClass().getName());

            System.out.println("方法的名称"+method.getName());

            if(args!=null&&args.length>0){

                   System.out.println("第一个参数"+args[0].toString());

                  

            }

            //执行目标代理

            Object result=method.invoke(this.targerService, args);

           

            return result;

     }

    

 

}

 

3.   cglib代理

  package cn.csdn.cglib;

 

import java.lang.reflect.Method;

 

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

 

 

 

 

publicclass CglibProxy  implements MethodInterceptor{

 

   

    //代理的目标对象   真实主题  角色

    private Object targetObject;

   

    // 根据目标对象创建代理对象

    public Object createPoxyInstrance(Object targetObject) {

       this.targetObject = targetObject;

       //用于创建目标对象的代理对象

       Enhancer enhancer = new Enhancer();

       enhancer.setSuperclass(this.targetObject.getClass());

       enhancer.setCallback(this);

      

       return enhancer.create(); //创建代理对象

      

 

    }

   

    @Override

    public Object intercept(Object proxy, Method method, Object[] args,MethodProxy arg3) throws Throwable {

        System.out.println("代理类的名称"+proxy.getClass().getName());

        System.out.println("方法的名称"+method.getName());

        if(args!=null && args.length>0){

            System.out.println("第一个参数"+args[0].toString());

        }

        

        //执行目标对象的方法

       Object result =  arg3.invoke(this.targetObject, args);

        

       return result;

    }

 

}

 

 

3.面向切面  

 

1》定义AOP术语

1.    切面:需要实现的交叉功能

2.    连接点:应用程序执行过程中插入切面的地点;此处可是方法调用,异常抛出甚至是要修改的字段

3.    通知:通知切面的实际实现。它通知应用系统的行为,通知在连接点插入到应用系统中

4.    切入点:定义了通知应该用在那些连接点。通常通过制定类名和方法名,或匹配类名和方法名式样的正则表达式来指定切入点。

5.    引入:允许为已存在类添加新的方法和属性

6.    目标对象:被通知对象,即可是编写的类也可是添加定制行为的第三方类

7.    代理:将通知应用到目标对象后创建的对象

8.    织入:将切面应用到目标对象从而创建一个新的代理对象的过程。切面在指定接入点被织入到目标对象中,织入发生在目标对象声明周期的多个点上:

编译器:切面在目标对象编译时织入

类装载器:切面在目标对象被载入到JVM时织入

运行期:切面在应用系统中运行时织入

9.    通知包括需要应用的交叉行为:连接点是通知要在应用系统需要应用的所有切入点;切入点定义了通知要在那些连接点应用。

2》      创建通知:

Around

接口Org.springframework.aop.MethodInterceptor

描述:拦截对目标方法调用

Before

接口:Org.springframework.aop.BeforeAdvice

描述:在目标方法调用前调用

After

接口:Org.springframework.aop.AfterReturningAdvice

描述:在目标方法调用后调用

Throw

接口:Org.springframework.aop.ThrowsAdvice

描述:当目标方法抛出异常时调用

案例:

 package cn.csdn.advice;

 

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

 

public class MyAroundAdvice 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;

   }

 

}

package cn.csdn.advice;

 

import java.lang.reflect.Method;

 

import org.springframework.aop.AfterReturningAdvice;

 

public class MyAfterAdivce  implements AfterReturningAdvice{

 

   @Override

   public void afterReturning(Object arg0, Method arg1, Object[] arg2,

                 Object arg3) throws Throwable {

          System.out.println("after++++++++++++++++方法的返回值"+arg0);

         

   }

 

}

 

package cn.csdn.advice;

 

import java.lang.reflect.Method;

 

import org.springframework.aop.MethodBeforeAdvice;

 

public class MyBeforeAdivce implements MethodBeforeAdvice{

 

   @Override

   public void before(Method arg0, Object[] arg1, Object arg2)

                 throws Throwable {

          //第一个参数:方法多得多对象

          //第二个参数:方法的参数

         

          //第三个参数:目标对象

         

         

          Object obj=null;

          if(arg1.length>0){

                 obj=arg1[0];

                

          }

          System.out.println("before*********方法的名称:::"+arg0.getName()+"  方法的第一个参数值"+obj.toString()+"  目标对象是:"+arg2.getClass());

}

 

}

package cn.csdn.advice;

 

import java.lang.reflect.Method;

 

import org.springframework.aop.ThrowsAdvice;

 

public class MyThrowsAdivce implements ThrowsAdvice{

  

   public void afterThrowing(Method method,Object[] args, Object target,Throwable throwable){

           System.out.println("exception----------------------------"+throwable.getMessage());

   }

}

 

 

引入通知:

/**

 *

 * 引入通知(引入的拦截器)

 *

 */

publicclass AuditableAdvice extends DelegatingIntroductionInterceptor implements Auditable{

 

   

    private Date lastModifiedDate;

    @Override

    publicvoid setLastModifiedDate(Date lastModifiedDate) {

       this.lastModifiedDate=lastModifiedDate;

      

    }

    @Override

    public Date getLastModifiedDate() {

       returnlastModifiedDate;

    }

 

}

 

 

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"

    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-2.5.xsd http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-lazy-init="true">

 

 

 

 

 

   <!-- 环绕通知 -->  

   <bean id="myAroundAdvice" class="cn.csdn.advice.MyAroundAdvice"/>

   <!-- 配置前置通知 -->

   <bean id="myBeforeAdvice" class="cn.csdn.advice.MyBeforeAdivce"/>

   <!-- 配置后置通知 -->

   <bean id="myAfterAdivce" class="cn.csdn.advice.MyAfterAdivce"/>

   <!-- 配置异常通知 -->

   <bean id="myThrowsAdivce" class="cn.csdn.advice.MyThrowsAdivce"/>

  

  

    <!-- 引入通知 -->

   <bean id="auditableAdvice" class="cn.csdn.advice.AuditableAdvice"/>

  

  

   <!-- 业务bean -->

   <bean id="personServiceBean" class="cn.csdn.service.PersonServiceBean"/>

  

   <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">

  

      <!-- 代理的接口 -->

      <property name="proxyInterfaces">

         <list>

           <value>cn.csdn.service.PersonService</value>

           <value>cn.csdn.advice.Auditable</value>

         </list>

      </property>

     

      <!--  通知名称-->

      <property name="interceptorNames">

         <list>

           <value>myBeforeAdvice</value>

           <value>myAroundAdvice</value>

           <value>myAfterAdivce</value>

           <value>myThrowsAdivce</value>

           <value>auditableAdvice</value>

         </list>

      </property>

     

      <!-- 通知的对象 -->

      <property name="target">

        <ref bean="personServiceBean"/>

      </property>

  

   </bean>

 

</beans> 

 


 

 

 

你可能感兴趣的:(spring,bean,object,null,Class,编译器)