Spring 通过XML配置文件以及通过注解形式来AOP 来实现前置,环绕,异常通知,返回后通知,后通知
本节主要内容:
一、Spring 通过XML配置文件形式来AOP 来实现前置,环绕,异常通知
1. Spring AOP 前置通知 XML配置使用案例
2. Spring AOP 环绕通知 XML配置使用案例
3. Spring AOP 抛出异常后通知 XML配置使用案例
4. Spring AOP 返回后通知 XML配置使用案例
5. Spring AOP 后通知 XML配置使用案例
二、Spring 通过注解形式来AOP 来实现前置,环绕,异常通知
1. Spring AOP 前置通知 注解使用案例
2. Spring AOP 环绕通知 注解使用案例
3. Spring AOP 抛出异常后通知 注解使用案例
4. Spring AOP 返回后通知 注解使用案例
5. Spring AOP 后通知 注解使用案例
本文作者:souvc
本文出处:http://www.cnblogs.com/liuhongfeng/p/4736947.html
AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,AOP实际是GoF设计模式的延续
关于Spring AOP的一些术语
- 切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现
- 连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行
- 通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before”和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链
- 切入点(Pointcut):定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。
通知类型
- 前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)
- 返回后通知(@AfterReturning):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
- 抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知
- 后通知(@After):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
- 环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行
Spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。以下是JDK动态代理和CGLIB代理简单介绍
JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
在Spring中,有接口时将采用JDK的方式实现proxy代理对象,当没有接口时,将采用cglib中的方式实现prixy代理对象。
一、 Spring 通过XML配置文件形式来AOP 来实现前置,环绕,异常通知
1 Spring AOP前置通知案例
1.1 问题
使用Spring AOP前置通知,在访问Controller中每个方法前,记录用户的操作日志。
1.2 方案
Spring AOP使用步骤:
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建Controller,创建新项目SpringAOP。
导入Spring 环境的jar包 :
如果没有jar包,那么可以上去上面下一个。下载地址:http://yunpan.cn/cdXTcJtZfJqQk 访问密码 6c96
创建员工业务控制器EmpController,并实现员工查询,代码如下:
package com.souvc.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 控制类
*
*/
@Controller
@RequestMapping("/emp")
public class EmpController { /**
* 方法名:find</br>
* 详述: 查询员工 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param userid
* @param password
* @return
* @throws
*/
@RequestMapping("/findEmp.do")
public String find(String userid,String password) { // 模拟查询员工数据
System.out.println("执行,find()方法,查询员工数据,发送至列表页面."); return "emp/emp_list.jsp";
}
}
步骤二:创建方面组件
创建方面组件OperateLogger,并在该类中创建记录用户操作日志的方法,代码如下:
package com.souvc.aspect; /**
* 用于记录日志的方面组件,演示Spring AOP的各种通知类型。
*/
public class OperateLogger { /**
* 方法名:log1</br>
* 详述:测试前置通知 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @throws
*/
public void log1() {
// 记录日志
System.out.println("进入log1()方法");
}
}
步骤三:声明方面组件
在applicationContext.xml中,声明该方面组件,关键代码如下:
<!-- 声明方面组件 --> <bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/>
步骤四:将方面组件作用到目标组件上
在applicationContext.xml中,将声明的方面组件作用到com.souvc.controller包下所有类的所有方法上,关键代码如下:
<!-- 声明方面组件 -->
<bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/> <!-- 配置AOP -->
<aop:config>
<aop:aspect ref="operateLogger">
<aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
</aop:config>
步骤五:测试
创建Junit测试类TestEmpController,并增加测试查询员工的方法,代码如下:
package com.souvc.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 控制类
*
*/
@Controller
@RequestMapping("/emp")
public class EmpController { /**
* 方法名:find</br>
* 详述: 查询员工 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param userid
* @param password
* @return
* @throws
*/
@RequestMapping("/findEmp.do")
public String find(String userid,String password) { // 模拟查询员工数据
System.out.println("执行,find()方法,查询员工数据,发送至列表页面."); return "emp/emp_list.jsp";
}
}
执行该测试方法,控制台输出效果:
进入log1()方法
执行,find()方法,查询员工数据,发送至列表页面.
可见,在执行EmpController.find()方法之前,执行了方面组件的记录日志的方法,由于该方法采用AOP面向对象的思想实现的,因此不需要对Controller类做任何改动。
2 Spring AOP环绕通知案例
2.1 问题
使用Spring AOP环绕通知,在访问Controller中每个方法前,记录用户的操作日志。
2.2 方案
Spring AOP使用步骤:
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建方面组件
复用方面组件OperateLogger,在该类中创建新的记录日志的方法log2,代码如下:
/**
* 方法名:log2</br>
* 详述:环绕通知使用的方法 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param p
* @return
* @throws Throwable
* @throws
*/
public Object log2(ProceedingJoinPoint p) throws Throwable {
// 目标组件的类名
String className = p.getTarget().getClass().getName();
// 调用的方法名
String method = p.getSignature().getName();
// 当前系统时间
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
// 拼日志信息
String msg = "-->用户在" + date + ",执行了" + className + "." + method + "()";
// 记录日志
System.out.println(msg);
// 执行目标组件的方法
Object obj = p.proceed();
// 在调用目标组件业务方法后也可以做一些业务处理
System.out.println("-->调用目标组件业务方法后...");
return obj;
}
步骤二:声明方面组件
由于复用的方面组件已经声明,因此该步骤可以省略。
步骤三:将方面组件作用到目标组件上
在applicationContext.xml中,声明方面组件的log2方法,关键代码如下:
<aop:aspect ref="operateLogger">
<aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
步骤四:测试
执行测试方法TestEmpController.test1(),控制台输出效果如下:
进入log1()方法
-->用户在2016-04-29 01:06:54,执行了com.souvc.controller.EmpController.find()
执行,find()方法,查询员工数据,发送至列表页面.
-->调用目标组件业务方法后..
项目详细代码:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 开启注解扫描 -->
<context:component-scan base-package="com.souvc" /> <!-- 支持@RequestMapping请求和Controller映射 -->
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 声明方面组件-->
<bean id="operateLogger" class="com.souvc.aspect.OperateLogger" /> <!-- 配置AOP -->
<aop:config> <!-- 测试前置通知 -->
<aop:aspect ref="operateLogger">
<aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect> <!-- 测试环绕通知 -->
<aop:aspect ref="operateLogger">
<aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect> </aop:config> </beans>
OperateLogger.java
package com.souvc.aspect; import java.text.SimpleDateFormat;
import java.util.Date; import org.aspectj.lang.ProceedingJoinPoint; /**
* 用于记录日志的方面组件,演示Spring AOP的各种通知类型。
*/
public class OperateLogger { /**
* 方法名:log1</br>
* 详述:测试前置通知 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @throws
*/
public void log1() {
// 记录日志
System.out.println("进入log1()方法");
} /**
* 方法名:log2</br>
* 详述:环绕通知使用的方法 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param p
* @return
* @throws Throwable
* @throws
*/
public Object log2(ProceedingJoinPoint p) throws Throwable {
// 目标组件的类名
String className = p.getTarget().getClass().getName();
// 调用的方法名
String method = p.getSignature().getName();
// 当前系统时间
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
// 拼日志信息
String msg = "-->用户在" + date + ",执行了" + className + "." + method + "()";
// 记录日志
System.out.println(msg);
// 执行目标组件的方法
Object obj = p.proceed();
// 在调用目标组件业务方法后也可以做一些业务处理
System.out.println("-->调用目标组件业务方法后...");
return obj;
} }
3 Spring AOP异常通知案例
3.1 问题
使用Spring AOP异常通知,在每个Controller的方法发生异常时,记录异常日志。
3.2 方案
Spring AOP使用步骤:
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建方面组件
复用方面组件OperateLogger,在该类中创建新的记录日志的方法log3,代码如下:
/**
* 方法名:log3</br>
* 详述:测试异常通知使用的方法</br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param e
* @throws
*/
public void log3(Exception e) {
StackTraceElement[] elems = e.getStackTrace();
// 将异常信息记录
System.out.println("-->" + elems[0].toString());
}
步骤二:声明方面组件
由于复用的方面组件已经声明,因此该步骤可以省略。
步骤三:将方面组件作用到目标组件上
在applicationContext.xml中,声明方面组件的log3方法,关键代码如下:
<aop:aspect ref="operateLogger">
<aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
关键配置代码:
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.souvc" /> <!-- 支持@RequestMapping请求和Controller映射 -->
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 声明方面组件-->
<bean id="operateLogger" class="com.souvc.aspect.OperateLogger" /> <!-- 配置AOP -->
<aop:config> <!-- 测试前置通知 -->
<aop:aspect ref="operateLogger">
<aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect> <!-- 测试环绕通知 -->
<aop:aspect ref="operateLogger">
<aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect> <!-- 测试异常通知 -->
<aop:aspect ref="operateLogger">
<aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect> </aop:config>
步骤四:测试
为了便于测试,在EmpController.find()方法中制造一个异常,代码如下:
主要代码:
// 制造一个异常,便于测试异常通知
//Integer.valueOf("abc");
五、测试效果
进入log1()方法
-->用户在2016-04-29 01:12:07,执行了com.souvc.controller.EmpController.find()
执行,find()方法,查询员工数据,发送至列表页面.
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
4 Spring AOP 后返回通知案例
4.1 问题
使用Spring AOP后返回通知类型。
4.2 方案
Spring AOP使用步骤:
4.3 步骤
实现此案例需要按照如下步骤进行。
5 Spring AOP 执行后案例
5.1 问题
使用Spring AOP 执行后通知类型。
5.2 方案
Spring AOP使用步骤:
5.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:
在 OperateLogger.java 添加以下代码:
/**
* 方法名:log5</br>
* 详述:测试 执行后使用的方法</br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param result
* @return
* @throws
*/
public void log5() {
// 记录日志
System.out.println("进入log5()方法");
}
步骤二:
在 applicationContext.xml 添加以下代码:
<!-- 测试后通知 -->
<aop:aspect ref="operateLogger">
<aop:after method="log5" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
步骤三:
运行测试类
步骤四:
效果如下:
进入log1()方法
-->用户在2016-04-29 01:53:10,执行了com.souvc.controller.EmpController.find()
执行,find()方法,查询员工数据,发送至列表页面.
进入log5()方法
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
二、 Spring 通过注解形式形式来AOP 来实现前置,环绕,异常通知
Spring AOP相关注解及含义如下:
@Aspect:用于声明方面组件
@Before:用于声明前置通知
@AfterReturning:用于声明后置通知
@After:用于声明最终通知
@Around:用于声明环绕通知
@AfterThrowing:用于声明异常通知
1 Spring AOP注解使用案例
1.1 问题
使用Spring AOP注解替代XML配置,重构上面的3个案例。
1.2 方案
分别在对应的方法上面加上注解。
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:开启AOP注解扫描
在applicationContext.xml中,去掉方面组件声明及作用的XML配置,并开启AOP注解扫描,关键代码如下:
<!-- 声明方面组件 -->
<!-- <bean id="operateLogger" class="com.souvc.aspect.OperateLogger" />--> <!-- 配置AOP --> <!-- <aop:config>
<aop:aspect ref="operateLogger">
<aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
<aop:aspect ref="operateLogger">
<aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
<aop:aspect ref="operateLogger">
<aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
</aop:config> -->
<!-- 开启AOP注解扫描 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
或者:
<!-- 启用spring对AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
步骤二:使用注解声明方面组件
在OperateLogger中,使用@Aspect注解声明方面组件,并分别用@Before、@Around、@AfterThrowing注解声明log1、log2、log3方法,将方面组件作用到目标组件上,代码如下:
package com.souvc.aspect; import java.text.SimpleDateFormat;
import java.util.Date; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; /**
* 用于记录日志的方面组件,演示Spring AOP的各种通知类型。
*/
@Component
@Aspect
public class OperateLogger { /**
* 方法名:log1</br>
* 详述:测试前置通知 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @throws
*/
@Before("within(com.souvc.controller..*)")
public void log1() {
// 记录日志
System.out.println("进入log1()方法");
} /**
* 方法名:log2</br>
* 详述:环绕通知使用的方法 </br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param p
* @return
* @throws Throwable
* @throws
*/
@Around("within(com.souvc.controller..*)")
public Object log2(ProceedingJoinPoint p) throws Throwable {
// 目标组件的类名
String className = p.getTarget().getClass().getName();
// 调用的方法名
String method = p.getSignature().getName();
// 当前系统时间
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
// 拼日志信息
String msg = "-->用户在" + date + ",执行了" + className + "." + method + "()";
// 记录日志
System.out.println(msg);
// 执行目标组件的方法
Object obj = p.proceed();
// 在调用目标组件业务方法后也可以做一些业务处理
System.out.println("-->调用目标组件业务方法后...");
return obj;
} /**
* 方法名:log3</br>
* 详述:测试异常通知使用的方法</br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param e
* @throws
*/
@AfterThrowing(pointcut = "within(com.souvc.controller..*)", throwing = "e")
public void log3(Exception e) {
StackTraceElement[] elems = e.getStackTrace();
// 将异常信息记录
System.out.println("-->" + elems[0].toString());
} /**
* 方法名:log4</br>
* 详述:测试 返回后通知使用的方法</br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param result
* @return
* @throws
*/
@AfterReturning(value="execution(* com.souvc.controller.*.*(..))",returning="result")
public void log4(JoinPoint joinPoint,Object result ){
Object object = joinPoint.getSignature();//方法返回值 System.out.println("joinPoint.getKind():"+ joinPoint.getKind());
System.out.println("joinPoint.getTarget():"+joinPoint.getTarget());
System.out.println("joinPoint.getThis():"+joinPoint.getThis());
System.out.println("joinPoint.getArgs():"+joinPoint.getArgs().length);
Object [] args=joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
System.out.println("参数:"+args[i]);
}
System.out.println("joinPoint.getSignature():"+joinPoint.getSignature());
System.out.println("joinPoint.getSourceLocation():"+joinPoint.getSourceLocation());
System.out.println("joinPoint.getStaticPart():"+joinPoint.getStaticPart()); String rightnow=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
System.out.println(rightnow+"执行了【"+object+"方法正常执行结束......】"+"【返回结果:"+result+"】");
} /**
* 方法名:log5</br>
* 详述:测试 执行后使用的方法</br>
* 开发人员:http://www.cnblogs.com/liuhongfeng/ </br>
* 创建时间:2016年4月29日 </br>
* @param result
* @return
* @throws
*/
// @After(value="execution(com.souvc.controller.*.*(..))")
// public void log5() {
// // 记录日志
// System.out.println("进入log5()方法");
// } }
步骤三:测试
执行测试方法TestEmpController.test1(),结果如下:
无异常的时候:
-->用户在2016-04-27 11:30:22,执行了com.souvc.controller.EmpController.find()
-->记录用户操作信息
查询员工数据,发送至列表页面.
-->调用目标组件业务方法后...
有异常的时候:
-->用户在2016-04-27 11:32:27,执行了com.souvc.controller.EmpController.find()
-->记录用户操作信息
查询员工数据,发送至列表页面.
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
Signature getSignature() :获取连接点的方法签名对象;
java.lang.Object getTarget() :获取连接点所在的目标对象;
java.lang.Object getThis() :获取代理对象本身;
java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;
java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。
本文作者:souvc
本文出处:http://www.cnblogs.com/liuhongfeng/p/4736947.html
其他的博文可以参考:
Spring 通过XML配置文件以及通过注解形式来AOP 来实现前置,环绕,异常通知,返回后通知,后通知的更多相关文章
- Spring 在 xml配置文件 或 annotation 注解中 运用Spring EL表达式
Spring EL 一:在Spring xml 配置文件中运用 Spring EL Spring EL 采用 #{Sp Expression Language} 即 #{spring表达式} ...
- JavaWeb_(Spring框架)xml配置文件
系列博文 JavaWeb_(Spring框架)xml配置文件 传送门 JavaWeb_(Spring框架)注解配置 传送门 Xml配置 a)Bean元素:交由Spring管理的对象都要配置在bean ...
- [error] eclipse编写spring等xml配置文件时只有部分提示,tx无提示
eclipse编写spring等xml配置文件时只有<bean>.<context>等有提示,其他标签都没有提示 这时就需要做以下两步操作(下面以事务管理标签为例) 1,添加命 ...
- Spring框架xml配置文件 复杂类型属性注入——数组 list map properties DI dependency injection 依赖注入——属性值的注入依赖于建立的对象(堆空间)
Person类中的各种属性写法如下: package com.swift.person; import java.util.Arrays; import java.util.List; import ...
- Spring根据XML配置文件注入对象类型属性
这里有dao.service和Servlet三个地方 通过配过文件xml生成对象,并注入对象类型的属性,降低耦合 dao文件代码: package com.swift; public class Da ...
- 如何配置多个Spring的xml配置文件(多模块配置)
如何使用多个Spring的xml配置文件(多模块配置) (2009-08-22 13:42:43) 如何使用多个Spring的xml配置文件(多模块配置) 在用Struts Spring Hibe ...
- @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationEx ...
- Spring的xml配置文件中约束的必要性 找不到元素 'beans' 的声明
今天在复习Spring MVC框架的时候,只知道xml配置文件中的约束有规范书写格式的作用,所以在配置HandlerMapping对象信息的时候没有加入约束信息之后进行测试,没有遇到问题.后来在配置S ...
- Spring读取xml配置文件的原理与实现
本篇博文的目录: 一:前言 二:spring的配置文件 三:依赖的第三方库.使用技术.代码布局 四:Document实现 五:获取Element的实现 六:解析Element元素 七:Bean创造器 ...
随机推荐
- Week4 结对编程
1.照片 1.1 结对编程参与者:李文涛.黎柏文 1.2 展示照片 2.结对编程的优点&缺点 2.1 优点 2.1.1.两人分工合作,减少了工作量 2.1.2.结对编程的伙伴往往能提供不同 ...
- IE11之F12 Developer Tools--DOM Explorer
使用DOM Explorer工具查看网页的DOM状态.检查HTML结构和CSS样式,并测试更改以解决显示问题.这可以在元素位置错误或行为异常时帮助你诊断问题,然后解决问题. DOM Explorer图 ...
- visual studio 局域网远程调试web项目
1.进入项目根目录,找到.vs/config/applicationhost.config文件(可能是隐藏的) 2.搜索sites节点,找到当前项目,并添加一个binding配置节,将ip地址设置为本 ...
- 【C#进阶系列】03 配置文件管理与程序集的引用版本重定向
先来点与标题不相关的: CLR支持两种程序集:弱命名程序集和强命名程序集. 两者的区别在于强命名程序集使用发布者的公钥和私钥进行签名.由于程序集被唯一性地标识,所以当应用程序绑定到强命名程序集时,CL ...
- [moka同学笔记]yii2.0数据库操作以及分页
1.model中models/article.php 1 <?php 2 3 namespace app\models; 4 5 use Yii; 6 7 /** 8 * This is the ...
- python pip 升级每个包
pip本身不自带升级所有包的功能, 但可以通过下面的脚本实现. import pip from subprocess import call for dist in pip.get_installed ...
- maven nexus deploy方式以及相关注意事项
以前公司都是配管负责管理jar的,现在没有专职配管了,得自己部署到deploy上供使用.总的来说,jar部署到nexus上有两种方式: 1.直接登录nexus控制台进行上传,如下: 但是,某些仓库可能 ...
- 一些arcgis符号库干货
分享一些arcgis符号库干货,自己也可以参考网上的教程自己做,但尽量要符合标准规范. 下面是一些符号示例(并不一定是官方标准的): 土地利用总体规划图 水土保持图 1:5万土地利用现状 1:1万地形 ...
- 我的Fitbit Force手环使用体验
2013年底,从淘宝上代购了Fitbit Force二代,下手前也对比了当时的几个类似产品,好像记得Nike新款暂时在国内还买不到,就买下了这个,1020元,时至今日好像只需六.七百了.当时看中它的主 ...
- VS2015发布Webservice
第一步:开启IIs:在控制面板程序——>程序功能——>打开或关闭windows功能,把“Internet信息服务”下面的“FTP服务器”.“Web管理工具”.“万维网服务”全部勾上,然后点 ...