Spring框架第二讲

来源:互联网 发布:网络大v的责任 编辑:程序博客网 时间:2024/05/16 08:42

概述:今天主要讲解spring的注解使用和分散配置、AOP的介绍

一、spring的注解

简介:在 Spring 2.5中已经可以用注解的方式去驱动 Spring 的依赖注射了,@Autowired注解提供了更细致的控制与更好的适应性。Spring 2.5 也支持 JSR-250 中的一些注解,例如@Resource,@PostConstruct,以及@PreDestroy。

a) @Autowired注解配置第一种

Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。@Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。要使@Autowired能够工作,还需要在配置文件中加入以下 

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />   

b) 开启所有的注解

首先加入命名空间和地址,引入context的上下文标签,再使用context:annotation-config标签 

该配置可激活在类中探测到的各种注解,@Required @Autowired @PostConstruct @PreDestroy @Resource @EJB @PersistenceContext @WebServiceRef等等,

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"       

    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:annotation-config />        

beans>  

二、分散配置

a) 引入外部bean来读取外部配置文件 这样在<value>${name}</value>可以使用这个占位符来注入值了

<!--第一种,引入外部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>

b) 使用spring自带的context工具来读取外部文件

首先需要引入springcontext的命名空间和连接地址 。然后使用

<context:property-placeholder location="person.properties"/>来引入文件

c) 定制编辑器后处理类

i. 在配置文件中配置

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

      <property name="customEditors">

         <map>

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

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

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

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

             </entry>

         </map>

      </property>

 </bean>

ii. 在java中首先需要继承PropertyEditorSupport这个类然后实现setAsText方法,代码如下

public class AddressEditor extends PropertyEditorSupport{

@Override

public void setAsText(String text) throws IllegalArgumentException {

// TODO Auto-generated method stub

//java实现转换

if(!"".equals(text)){

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

 if(args.length>3){

      Address address = new Address();

      address.setProvince(args[0]);

      address.setCity(args[1]);

      address.setStreet(args[2]);

      address.setZipCode(args[3]);

             setValue(address);

      }else{

      this.setAsText(null);

      }

}else{

this.setAsText(null);

}

}

三、AOP的介绍

概述:  1.切面(aspect):要实现的交叉功能,是系统模块化的一个切面或领域。如日志记录。

  2.连接点:应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出,或者要修改的

               字段。

  3.通知:切面的实际实现,他通知系统新的行为。如在日志通知包含了实

            现日志功能的代码,如向日志文件写日志。通知在连接点插入到应用系统中。

  4.切入点:定义了通知应该应用在哪些连接点,通知可以应用到AOP框架支持的任何连接点。

  5.引入:为类添加新方法和属性。

  6.目标对象:被通知的对象。既可以是你编写的类也可以是第三方类。

  7.代理:将通知应用到目标对象后创建的对象,应用系统的其他部分不用为了支持代理对象而

            改变。

  8.织入:将切面应用到目标对象从而创建一个新代理对象的过程。织入发生在目标

            对象生命周期的多个点上:

            编译期:切面在目标对象编译时织入.这需要一个特殊的编译器.

            类装载期:切面在目标对象被载入JVM时织入.这需要一个特殊的类载入器.

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

a) 环绕通知

在java类中实现MethodInterceptor接口

public class MyAroundAdvice implements MethodInterceptor{

@Override

public Object invoke(MethodInvocation methodInvocation) throws Throwable {

// TODO Auto-generated method stub

System.out.println("执行方法之前执行一些操作");

Object obj=methodInvocation.proceed();

System.out.println("执行方法之后执行一些操作");

return obj;

}

}

在配置文件中配置

<!--业务bean-->

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

<!--环绕通知-->

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

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

<property name="proxyInterfaces">

<list>

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

</list>

</property>

<!--通知名称-->

<property name="interceptorNames">

<list>

<value>myThrowsAdvice</value>

</list>

</property>

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

<property name="target">

<ref bean="personServiceBean"/>

</property>

b) 前置通知

public class MyBeforeAdvice implements MethodBeforeAdvice{

@Override

public void before(Method method, Object[] args, Object target)

throws Throwable {

// TODO Auto-generated method stub

//第一个参数  方法对象

//第二个参数  方法参数

//第三个参数  目标对象

Object arg=null;

if(args.length>0){

arg=args[0];

}

System.out.println("方法名:"+method.getName()+"---方法第一个参数的值"+arg+"目标对象是:"+target.toString());

}

}

在配置文件中声明该通知并在通知名称中加入<value>myBeforeAdvice</value>

<!--前置通知声明-->

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

c) 后置通知

public class MyAfterAdvice implements AfterReturningAdvice {

@Override

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

Object arg3) throws Throwable {

// TODO Auto-generated method stub

System.out.println("after---------------------方法的返回值是:"+returnValue);

}

}

配置文件中和前置通知类似

d) 异常通知

public class MyThrowsAdvice implements ThrowsAdvice {

//异常处理操作

public void afterThrowing(Throwable throwable){

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

}

}

配置文件中与前置通知类似

e) 引入通知

i. 声明接口

//添加一个属性 记录最后一次修改的时间

public interface Auditable {

void setLastModifiedDate(Date lastModifiedDate);

Date getLastModifiedDate();

}

ii. 引入拦截器并实现声明的接口

public class AuditableBean extends DelegatingIntroductionInterceptor implements Auditable{

private Date lastModifiedDate;

@Override

public void setLastModifiedDate(Date lastModifiedDate) {

// TODO Auto-generated method stub

this.lastModifiedDate=lastModifiedDate;

}

@Override

public Date getLastModifiedDate() {

// TODO Auto-generated method stub

return this.lastModifiedDate;

}

}

iii. 在配置文件中配置

<!--引入通知声明-->

   <bean id="auditableBean" class="cn.csdn.service.AuditableBean"/>

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

<property name="proxyInterfaces">

<list>

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

<!--将引入通知加入-->

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

</list>

</property>

<!--通知名称-->

<property name="interceptorNames">

<list>

<value>myThrowsAdvice</value>

<value>myAroundAdvice</value>

<value>myBeforeAdvice</value>

<value>myAfterAdvice</value>

<!--加入通知名称-->

<value>auditableBean</value>

</list>

</property>

原创粉丝点击