• Spring浅谈


                        Spring的使用

     Spring配置文件是用于指导Spring工厂进行Bean生产、依赖关系注入(装配)及Bean实例分发的"图纸"。Java EE程序员必须学会并灵活应用这份"图纸"准确地表达自己的"生产意图"。Spring配置文件是一个或多个标准的XML文档,applicationContext.xml是Spring的默认配置文件,当容器启动时找不到指定的配置文档时,将会尝试加载这个默认的配置文件。

    下面讲一下我在项目中所使用的两个技术set注入和拦截器。

    一、Set注入

    Spring有两种注入方式分别是构造注入和set注入。相应的在applicationContext.xml配置分别是:

    <beans>

    <bean id=”HelloWorld” class=”com.gc.action.HelloWorld” depends-on=”date”>

     <property name=”msg”>

    <value>HelloWorld</value>

    </property>

    <property name=”date”>

    <ref local=”date”/>

    </property>

    </bean>

    <bean id=”date” class=”java.util.Datte”/>

    </beans>

    上面是一个简单的配置文件。<bean></bean>用来指定有哪些类,<property></property>用来指定该类中有哪些变量,<value></value>用来指定一般变量的数值。<ref>用来引用其他类,Depens-on用来说明该类依赖其他类,就是说先初始化其他类,然后才能初始化这个类。这这里我们不写这个depens-on也行,因为date是其变量,初始化时候自然进行初始化了。上面的ref local表明“date”是在一个配置文件中配置的,如果是不同的则用ref bean。一般我们使用ref bean。因为ref bean即可以是在一个xml文件里配置的,也可以是在不同的xml配置的。

    上面我们采用的是set方法,一般我们都采用set方式注入。

    注入对java中函数有要求:

    Public class HelloWorld{

    Private String msg=null;//必须有msg这个变量,而且名字要和配置文件中的property中一样

    Private Date date=null//同上面所描述的一样。

    Public void setMsg(string msg)//必须有set+变量名首字母大写,这是规定,而且参数只有一个,类型和上面相同。则HelloWorld在创建时候会自动调用set方法,将配置文件中的value传进去。

    {

             this.msg=msg;

    }

    Public String  getMsg()//必须有set+变量名首字母大写,这是规定,而且参数只有一个,类型和上面相同

    {return this.msg;

             this.msg=msg;

    }

    同理setDate,getDate();

    到目前为止,我们就配置好一个完整的简单的类。

    我们随便写一个类来测试;

    Public class testHelloworld{

     Public static void main(string[] args){

             ApplicationContext actx=new FileSystemXmlApplicationContext(“config.xml”);//里面填你配置文件相对该.java的相对路径

    HelloWorld helloWorld=(HelloWorld)actx.getBean(“HelloWorld”);

    System.out.println(helloWorld.getMsg());

    }

    }

    执行就会输出value中的数值 HelloWorld。

    还有自动装在,就是在配置文件中我们不用写ref类型的。我们有byName,byType等。基本上大同小异。一般大型项目不推荐采用自动装配。下面我们还以上面例子进行讲解。

    HelloWorld.java文件不用改动。我们只需要在配置文件中将<bean id=”HelloWorld” class=”com.gc.action.HelloWorld”autowire=”byName”>

    将<property name= “date”>……….</property>这段去了。

    程序运行时候,HelloWorld.java包含一个名字叫date变量,Spring就会在配置文件中找id或name是date的Bean定义,然后用它来设置date属性。

    在大型的应用,不鼓励使用自动装配,因为它去除了参考依赖的透明性和清晰性。

    另外还有集合的注入,如Map,Set,List等,不一一介绍,用到再百度使用。

    二、拦截器

    AOP意识是面向方面编程,Aspect Oriented Programming,它使开发人员可以更好的将本来不应该彼此粘合在一起的功能分开。

    开发人员在编写程序时候,通常有两种代码,一种是和业务系统有关的代码,一种是和业务系统关系不大的代码,例如日志、权限、异常处理、事务处理等,以前编写代码时,是将这两种代码写在一起,这样写程序,就会出现程序中有很多相同或雷同的代码。如日志信息的输出,每个方法都要写日志,不利于程序的维护。而AOP可以实现则两类代码的分离,达到代码的复用。

    AOP有三个概念:Pointcut(插入点),Advice(插入的代码)和Advisor(负责将代码插入到插入点)

    Pointcut是Join Point连接点,就是我将要在那些函数,以及那些类的方法中插入我的Advice。如日志输出,Advice是负责日志输出,JoinPoint是负责业务的,我想在处理业务时候输出日志,就将处理业务的函数中插入Advice就好。

    Advisor是将Advice注入到Pointcut的代码。以日志为例,也就是将日志输出这段代码插入到业务处理函数中的那部分代码。

    1. 如何配置AOP呢,下面用最常见的方式进行讲解:

    1.1首先将一下Advice

    Spring提供五种类型的Advice:Interception Around(在调用前后执行)、Before(在调用前执行),After Returning(在调用返回后执行),Throw(在抛出异常后执行)

    Interception Around:

    Interception Around会在JointPoint的前后执行。实现Interception Around通知的类需要实现接口MethodInterceptor,代码如下:

    Public class test implements MethodInterptor{

    //重写invoke

    Public Object invoke(MethodInvocation invocation)throws Throwable{

     System.out.println(“开始审核数据”);

    Object rval=invocation.proceed();//执行JointPoint代码

    System.out.printtln(“审核数据结束”);

    Return rval;

    }

    }

    Before通知只在JointPoint前执行,实现Before通知的类需要实现MethodBeforeAdvice,代码如下:

    Public class test implements MethodBeforeAdvice{

    //重写invoke

    Public Object before(Method m,Object[]args,Object target)throws Throwable{

     System.out.println(“开始审核数据”);

    }

    }

    同理AfterReturningAdvice,方法是void afterReturning(Method m,Object[]args,Object target)throws Throwable;

    ThrowsAdvice方法是void afterThrowing(RemoteException ex)throws Throwable;

    1.2通过RegexpMethodPointcutAdvisor来配置Pointcut和相应的Advice,下面来个例子:

    配置文件如下:

    <bean ib=”logBefore” class=”com.gc.action.LogBefore”

    <bean id=”mylogBeforeAdvisor” class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>//用这个配置器

      <property name=”advice”><ref bean=”logBefore”/></property>//配置的advice

    <property name=”patterns”><value>.*do.*</value></property>//所有以do开头的方法都是Pointcut

    </bean>

    我们在LogBefore.java代码:

    Public classLogBefore implements MethodBeforeAdvice{

    //重写invoke

    Public Object before(Method m,Object[]args,Object target)throws Throwable{

     System.out.println(“开始审核数据”);

    }

    }

    我们使用自动代理即DefaultAdvisorAtoProxyCreator,使用其他代理太麻烦和使用不方便。

    所以整个配置文件是:

    我们写一个TimeBook.java,代码如下:

    Public class TimeBook{

    Public void doCheck(String name){

    System.out.println(“账务关闭的相关程序正在执行。。。”);

    }

    }

    LogBefore.java上面已经写过。

    配置文件:

    <bean id=”timebook” class=”com.gc.action.TimeBook”>

    //使用自动代理

    <bean id=”autoProxyCreator” class=”org.springframework.aop.framework.autoproxy.DaultAdvisorAtoProxyCreator”/>

    <bean ib=”logBefore” class=”com.gc.action.LogBefore”

    <bean id=”mylogBeforeAdvisor” class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>//用这个配置器

      <property name=”advice”><ref bean=”logBefore”/></property>//配置的advice

    <property name=”patterns”><value>.*do.*</value></property>//所有以do开头的方法都是Pointcut

    </bean>

    写一个测试类测试一下:

    Public class testHelloworld{

     Public static void main(string[] args){

             ApplicationContext actx=new FileSystemXmlApplicationContext(“config.xml”);//里面填你配置文件相对该.java的相对路径

    TimeBook book=( TimeBook)actx.getBean(“timebook”);

    book.doCheck(“张三”)

    }

    }

    执行测试程序输出:张山开始审核数据,财务关闭的相关程序正在执行。说明是在doCheck()函数执行前调用了通知。

    三、数据库。我们使用自带的BasicDataSource类

    <bean id="dataSourceD" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

           <property name="driverClassName"><value>dm.jdbc.driver.DmDriver</value></property>

           <property name="url"><value>jdbc:dm://localhost:5236</value></property>

           <property name="username"><value>SYSDBA</value></property>

           <property name="password"><value>dnsenum</value></property>

           <property name="initialSize"><value>2</value></property>

           <property name="maxActive"><value>10</value></property>

           <property name="minIdle"><value>20</value></property>

           <property name="defaultReadOnly"><value>false</value></property>

           <property name="defaultAutoCommit"><value>true</value></property>

            <property name="validationQuery"> <value>select count(*) from DNS.t_zone</value></property>

        </bean>

    <bean id=”HelloWorld” class=”com.gc.action.HelloWorld” >

    <property name=”datesource”>

    <ref bean=”dataSourceD”/>

    </property>

    </bean>

    Public class HelloWorld{

    Private Datesource datesource =null;

    Public void setDatesource(Datesource msg){

             this. datesource =msg;

    }

    Public String  getDatesource(){return this. datesource;}

    }

    写一个测试程序:

        Public class testHelloworld{

     Public static void main(string[] args){

             ApplicationContext actx=new FileSystemXmlApplicationContext(“config.xml”);//里面填你配置文件相对该.java的相对路径

    HelloWorld book=( HelloWorld)actx.getBean(“HelloWorld”);

    Datesource  ds=book. getDatesource();//低版本JDK使用DriverManager

    Connection conn = ds.getConnection(); //就返回一个数据库连接

    Statement sm = conn.createStatement(); //进行数据库操作类

    String sqlString = "insert into bryanttesttable values(2,'bryant')"; 

    Sm.execute(sqlstring);

    }

    }

     

    不要做一个似懂非懂的人,做一个脚踏实地的程序员
  • 相关阅读:
    直播报名| Kylin on Parquet 介绍及快速上手
    直播 | Apache Kylin & Apache Hudi Meetup
    1. MySQL体系结构和存储引擎——MySQL体系结构、存储引擎、连接MySQL
    深入理解Java虚拟机(第三版)-13.Java内存模型与线程
    Redis 字典实现
    JVM 判断对象已死亡?
    堆内存常见的分配策略、 经典的垃圾收集器、CMS与G1收集器及二者的比较
    String.intern() 和常量池
    Java 对象的创建过程(五步)、对象的内存布局、对象的访问定位
    Java内存区域(运行时数据区域)详解、JDK1.8与JDK1.7的区别
  • 原文地址:https://www.cnblogs.com/xuexiaohei/p/4437246.html
Copyright © 2020-2023  润新知