Spring(二)
1.1 AOP概述
1.1.1什么是AOP
- AOP(Aspect Oriented Programing) 面向切面编程。
- AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)。

- Spring的AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。
- AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译的时候提供横向代码的织入。
1.1.2AOP底层原理
- 代理机制
- 动态代理(JDK的动态代理)
- JDK的动态代理,对实现了接口的类生成代理。
- 动态代理(JDK的动态代理)
1.1.3Spring的AOP代理
- JDK动态代理:对实现了接口的类生成代理
- CGLIB代理机制:对类生成代理
1.1.4AOP的术语
- joinpoint(连接点):所谓的连接点是指那些被拦截到的点。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点。
- pointcut(切入点):所谓的切入点是指我们要对那些joinpoint进行拦截的定义。
- Advice(通知/增强):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)。
- Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或属性。
- Target(目标对象):代理的目标对象。
- Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入。
- Proxy(代理):一个雷被AOP织入增强后,就产生了一个结果代理类。
- Aspect(切面):是切入点和通知(引介)的结合。

1.2 AOP底层实现
1.2.1JDK的动态代理
package cn.demo4;
public interface IUserDAO {
public void add();
public void update();
public void delete();
public void find();
}
package cn.demo4;
public class UserDAOImpl implements IUserDAO {
@Override
public void add() {
System.out.println("添加用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void find() {
System.out.println("查询用户");
}
}
package cn.demo4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserDAOProxy implements InvocationHandler {
private IUserDAO iUserDAO;
public UserDAOProxy(IUserDAO iUserDAO){
this.iUserDAO = iUserDAO;
}
public IUserDAO getProxy(){
Object result = Proxy.newProxyInstance(iUserDAO.getClass().getClassLoader(), iUserDAO.getClass().getInterfaces(),this );
return (IUserDAO) result;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("add")){
System.out.println("日志记录");
Object result = method.invoke(iUserDAO, args);
System.out.println("日志记录");
return result;
}
if(method.getName().equals("delete")){
System.out.println("日志记录");
Object result = method.invoke(iUserDAO, args);
System.out.println("日志记录");
return result;
}
return method.invoke(iUserDAO, args);
}
}
package cn.demo4;
import org.junit.Test;
public class TestDemo {
@Test
public void demo1(){
IUserDAO iUserDAO = new UserDAOImpl();
IUserDAO proxy = new UserDAOProxy(iUserDAO).getProxy();
proxy.add();
proxy.delete();
proxy.find();
proxy.update();
}
}
1.2.2CGLIB动态代理
package cn.demo5;
public class ProductDAO {
public void add(){
System.out.println("添加商品");
}
public void delete(){
System.out.println("删除商品");
}
public void update(){
System.out.println("修改商品");
}
public void find(){
System.out.println("查询商品");
}
}
package cn.demo5;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class ProductDAOProxy implements MethodInterceptor{
private ProductDAO productDAO;
public ProductDAOProxy(ProductDAO productDAO){
this.productDAO = productDAO;
}
public ProductDAO getProxy(){
//创建CGLIB的核心类
Enhancer enhancer = new Enhancer();
//为其设置父类
enhancer.setSuperclass(productDAO.getClass());
//设置回调
enhancer.setCallback(this);
//创建代理
return (ProductDAO) enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().equals("add")){
System.out.println("日志记录");
return methodProxy.invokeSuper(proxy, args);
}
if(method.getName().equals("delete")){
System.out.println("日志记录");
return methodProxy.invokeSuper(proxy, args);
}
return methodProxy.invokeSuper(proxy, args);
}
}
package cn.demo5;
import org.junit.Test;
public class TestDemo {
@Test
public void demo1(){
ProductDAO proxy = new ProductDAOProxy(new ProductDAO()).getProxy();
proxy.add();
proxy.delete();
proxy.find();
proxy.update();
}
}
1.3 Spring中的AOP
1.3.1Spring的传统AOP
- AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice。
- Spring按照通知Advice在目标类方法的连接点位置,可以分为
- 前置通知org.springframework.aop.MethodBeforeAdvice
- 在目标方法执行前实施增强
- 后置通知org.springframework.aop.AfterReturningAdvice
- 在目标方法执行后实施增强
- 环绕通知org.aopalliance.intercept.MethodInterceptor
- 在目标方法执行前后实施增强
- 异常抛出通知org.springframework.aop.ThrowsAdvice
- 在方法抛出异常后实施增强
- 引介通知org.springframework.aop.IntroductionInterceptor
- 在目标类中添加一些新的方法和属性
- 前置通知org.springframework.aop.MethodBeforeAdvice
1.3.2Spring中的切面类型
- Advisor:Spring中传统切面。
- Advisor:都是一个切点和一个通知组合。
- Aspect:多个切点和多个通知的组合。
- Advisor:代表一般切面。Advisor本身就是一个切面,对目标类所有哦方法进行拦截。(不带有切点的切面,针对所有方法进行拦截)
- PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类那些方法(带有切点的切面,针对某个方法进行拦截)
- IntroductionAdvisor:代表引介切面,针对引介通知而使用切面。
1.3.3Spring的AOP的开发--针对所有方法的增强(不带切点的切面)
- 导入相应的jar包
- spring-aop-3.2.0.RELEASE.jar
- com.springsource.org.aopalliance-1.0.0.jar
- 编写被代理的接口和实现类
package cn.demo6;
public interface ICustomerDAO {
public void add();
public void delete();
public void update();
public void find();
}
package cn.demo6;
public class CustomerDAOImpl implements ICustomerDAO {
@Override
public void add() {
System.out.println("添加用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void find() {
System.out.println("查询用户");
}
}
- 编写增强的代码
package cn.demo6;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice {
/**
* @param method 执行的方法
* @param args 参数
* @param target 目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强");
}
}
- 生成代理(配置生成代理)
- Spring基于ProxyFactoryBean类,底层自动选择使用JDK的动态代理还是CGLIB的代理。
<?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"
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">
<!-- 定义目标对象 -->
<bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
<!-- 生成代理 -->
<!-- Spring支持配置生成代理 -->
<bean id="customerDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="customerDAO"/>
<!-- 设置实现接口 value接口的全路径-->
<property name="proxyInterfaces" value="cn.demo6.ICustomerDAO" />
<!-- 拦截的名称 -->
<property name="interceptorNames" value="beforeAdvice"/>
</bean>
</beans>
- 测试
package cn.demo6;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("customerDAOProxy")
private ICustomerDAO customerDAO;
@Test
public void demo1(){
customerDAO.add();
customerDAO.delete();
customerDAO.update();
customerDAO.find();
}
}
1.3.4Spring的AOP的开发--针对某些方法的增强(带有切点的切面)
- 创建被代理对象
package cn.demo7;
public class OrderDAO {
public void add(){
System.out.println("增加");
}
public void delete(){
System.out.println("删除");
}
public void find(){
System.out.println("查询");
}
public void update(){
System.out.println("修改");
}
}
- 编写要增强的类
package cn.demo7;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("方法执行前--日志记录");
Object result = invocation.proceed();
System.out.println("方法执行后--日志记录");
return result;
}
}
- 生成代理
<!-- 定义切点切面 -->
<bean id="pointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 定义表达式来规定哪些方法执行拦截 -->
<property name="pattern" value="cn.demo7.OrderDAO.add.*"/>
<!-- 应用增强 -->
<property name="advice" ref="aroundAdvice"/>
</bean>
<!-- 定义目标对象 -->
<bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
<!-- 定义增强 -->
<bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
<!-- 定义生成的代理对象 -->
<bean id="orderDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目标 -->
<property name="target" ref="orderDAO"></property>
<!-- 针对类的代理 -->
<property name="proxyTargetClass" value="true"/>
<!-- 在目标上应用增强 -->
<property name="interceptorNames" value="pointcutAdvisor"/>
</bean>
- 测试类
package cn.demo7;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("orderDAOProxy")
private OrderDAO orderDAO;
@Test
public void demo1(){
orderDAO.add();
orderDAO.delete();
orderDAO.find();
orderDAO.update();
}
}
1.3.5自动代理
- 前面的案例中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大。
- 自动创建代理:-----基于后处理Bean,在Bean创建的过程中完成的增强。生成的Bean就是代理。
- BeanNameAutoProxyCreator根据Bean名称创建
package cn.demo6;
public interface ICustomerDAO {
public void add();
public void delete();
public void update();
public void find();
}
package cn.demo6;
public class CustomerDAOImpl implements ICustomerDAO {
@Override
public void add() {
System.out.println("添加用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void find() {
System.out.println("查询用户");
}
}
package cn.demo6;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice {
/**
* @param method 执行的方法
* @param args 参数
* @param target 目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强");
}
}
package cn.demo7;
public class OrderDAO {
public void add(){
System.out.println("增加");
}
public void delete(){
System.out.println("删除");
}
public void find(){
System.out.println("查询");
}
public void update(){
System.out.println("修改");
}
}
package cn.demo7;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("方法执行前--日志记录");
Object result = invocation.proceed();
System.out.println("方法执行后--日志记录");
return result;
}
}
<?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"
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">
<!-- 定义目标对象 -->
<bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
<!-- 定义目标对象 -->
<bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
<!-- 定义增强 -->
<bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
<!-- 自动代理:按名称的代理 基于后处理Bean,后处理Bea不需要配置id -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
<property name="beanNames" value="*DAO"/>
<property name="interceptorNames" value="beforeAdvice"/>
</bean>
</beans>
package cn.demo8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.demo6.ICustomerDAO;
import cn.demo7.OrderDAO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class SpringTest {
@Autowired
@Qualifier("customerDAO")
private ICustomerDAO customerDAO;
@Autowired
@Qualifier("orderDAO")
private OrderDAO orderDAO;
@Test
public void demo1(){
orderDAO.add();
orderDAO.delete();
customerDAO.add();
customerDAO.delete();
}
}
- DefaultAdvisorAutoProxyCreator根据Advisor本身包含信息创建代理
package cn.demo6;
public interface ICustomerDAO {
public void add();
public void delete();
public void update();
public void find();
}
package cn.demo6;
public class CustomerDAOImpl implements ICustomerDAO {
@Override
public void add() {
System.out.println("添加用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void find() {
System.out.println("查询用户");
}
}
package cn.demo6;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice {
/**
* @param method 执行的方法
* @param args 参数
* @param target 目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强");
}
}
package cn.demo7;
public class OrderDAO {
public void add(){
System.out.println("增加");
}
public void delete(){
System.out.println("删除");
}
public void find(){
System.out.println("查询");
}
public void update(){
System.out.println("修改");
}
}
package cn.demo7;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("方法执行前--日志记录");
Object result = invocation.proceed();
System.out.println("方法执行后--日志记录");
return result;
}
}
<?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"
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">
<!-- 定义目标对象 -->
<bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
<!-- 定义目标对象 -->
<bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
<!-- 定义增强 -->
<bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
<!-- 定义一个带有切点的切面 -->
<bean id="pointcut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern" value=".*add.*"/>
<property name="advice" ref="aroundAdvice"/>
</bean>
<!-- 自动生成代理 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>
</beans>
package cn.demo9;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.demo6.ICustomerDAO;
import cn.demo7.OrderDAO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class SpringTest {
@Autowired
@Qualifier("customerDAO")
private ICustomerDAO customerDAO;
@Autowired
@Qualifier("orderDAO")
private OrderDAO orderDAO;
@Test
public void demo1(){
orderDAO.add();
orderDAO.delete();
customerDAO.add();
customerDAO.delete();
}
}
- AnnotationAwareAspectAutoProxyCreator基于Bean中的AspectJ注解进行自动代理。
区分基于ProxyFactoryBean的代理与自动代理的区别?
- ProxyFactoryBean是先有被代理的对象,将被代理的对象传入代理类中生成代理。
- 自动代理是基于后处理Bean,在Bean生成过程中产生了代理对象,把代理对象返回,生成的Bean已经是代理对象了。
1.4 Spring的AspectJ的AOP
1.4.1AspectJ简介
- AspectJ是一个基于Java语言的AOP框架。
- Spring2.0以后新增了对AspectJ切点表达式支持。
- @AspectJ是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面。
- 新版本的Spring框架,建议使用AspectJ方式来开发AOP。
1.4.2AspectJ表达式
- 语法:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
- execution(public * *(..)) 匹配所有类public方法
- execution(* cn.spring3.demo1.dao.*(..)) 匹配cn.spring3.demo1.dao包下的所有方法
- execution(* cn.spring3.demo1.dao..*(..)) 匹配cn.spring3.demo1.dao包及子包的所有方法
- execution(* cn.spring3.demo1.dao.GenericDAO+.*(..)) 匹配GenericDAO
- execution(* save(..)) 匹配所有save开头的方法
例如:(*在正则表达式中表示任意多次,0,1或多次;.表示任意字符)
1.4.3AspectJ提供不同的通知类型
- @Before 前置通知
- @AfterReturning 后置通知
- @Around 环绕通知
- @AfterThrowing 抛出通知
- @After 最终通知,不管是否异常,该通知都会执行
- @DeclareParents引介通知
1.4.4基于注解
- 引入相应的jar包
- spring-aop-3.2.0.RELEASE.jar
- com.springsource.org.aopalliance-1.0.0.jar
- spring-aspects-3.2.0.RELEASE.jar
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- 编写被增强类(目标类)
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public void find(){
System.out.println("查询用户");
}
}
- 使用AspectJ注解形式
package cn.demo1;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.*(..))")
public void before(){
System.out.println("前置增强。。。。");
}
}
- 创建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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
- 测试类
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
1.4.4AspectJ通知类型
- @Before 前置通知,在方法之前执行,没有办法阻止目标方法执行。
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public void find(){
System.out.println("查询用户");
}
}
package cn.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
- @AfterReturning 后置通知,获取方法的返回值。
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public int find(){
System.out.println("查询用户");
return 1;
}
}
package cn.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
@AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
public void afterReturning(Object returnVal){
System.out.println("后置增强。。。。"+returnVal);
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
- @Around 环绕通知,可以在方法之前和方法之后执行的,可以阻止目标方法的执行。
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public int find(){
System.out.println("查询用户");
return 1;
}
}
package cn.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
@AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
public void afterReturning(Object returnVal){
System.out.println("后置增强。。。。"+returnVal);
}
@Around(value="execution(* cn.demo1.UserDAO.update(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前增强");
Object obj = joinPoint.proceed();
System.out.println("环绕后增强");
return obj;
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
- AfterThrowing抛出异常通知
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public int find(){
System.out.println("查询用户");
int i = 1/0;
return 1;
}
}
package cn.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
@AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
public void afterReturning(Object returnVal){
System.out.println("后置增强。。。。"+returnVal);
}
@Around(value="execution(* cn.demo1.UserDAO.update(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前增强");
Object obj = joinPoint.proceed();
System.out.println("环绕后增强");
return obj;
}
@AfterThrowing(value="execution(* cn.demo1.UserDAO.find(..))",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("出异常了。。。"+e.getMessage());
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
- After 最终通知
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public int find(){
System.out.println("查询用户");
int i = 1/0;
return 1;
}
}
package cn.demo1;
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;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
@AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
public void afterReturning(Object returnVal){
System.out.println("后置增强。。。。"+returnVal);
}
@Around(value="execution(* cn.demo1.UserDAO.update(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前增强");
Object obj = joinPoint.proceed();
System.out.println("环绕后增强");
return obj;
}
@AfterThrowing(value="execution(* cn.demo1.UserDAO.find(..))",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("出异常了。。。"+e.getMessage());
}
@After(value="execution(* cn.demo1.UserDAO.find(..))")
public void after(){
System.out.println("最终通知");
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
1.4.5切点的注解
- 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@Pointcut进行定义。
- 切点方法:private void 无参方法,方法名为切点名。
- 当多个切点时,可以使用||进行连接。
package cn.demo1;
public class UserDAO {
public void add(){
System.out.println("添加用户");
}
public void update(){
System.out.println("修改用户");
}
public void delete(){
System.out.println("删除用户");
}
public int find(){
System.out.println("查询用户");
int i = 1/0;
return 1;
}
}
package cn.demo1;
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.aspectj.lang.annotation.Pointcut;
/**
* 切面类:就是切点与增强的结合
* @author love
*
*/
@Aspect
public class MyAspect {
@Before("execution(* cn.demo1.UserDAO.add(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置增强。。。。"+joinPoint);
}
@AfterReturning(value="MyAspect.pointcut()",returning="returnVal")
public void afterReturning(Object returnVal){
System.out.println("后置增强。。。。"+returnVal);
}
@Around(value="execution(* cn.demo1.UserDAO.update(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前增强");
Object obj = joinPoint.proceed();
System.out.println("环绕后增强");
return obj;
}
@AfterThrowing(value="MyAspect.pointcut()",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("出异常了。。。"+e.getMessage());
}
@After("MyAspect.pointcut()")
public void after(){
System.out.println("最终通知");
}
@Pointcut("execution(* cn.demo1.UserDAO.find(..))")
private void pointcut(){}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 开启自动生成代理 -->
<aop:aspectj-autoproxy/>
<bean id="userDAO" class="cn.demo1.UserDAO"/>
<bean id="myAspect" class="cn.demo1.MyAspect"/>
</beans>
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
userDAO.add();
userDAO.delete();
userDAO.find();
userDAO.update();
}
}
- Advisor和Aspect的区别?
- Advisor:Spring传统意义上的切面,支持一个切点和一个通知的组合。
- Aspect:支持多个切点和多个通知的组合。
1.4.6基于XML
- 定义被增强的类--目标类
package cn.demo2;
public class ProductDAO {
public void add(){
System.out.println("添加商品");
}
public void update(){
System.out.println("修改商品");
}
public void delete(){
System.out.println("删除商品");
}
public void find(){
System.out.println("查询商品");
}
}
- 定义切面
package cn.demo2;
/**
* 切面类
*/
public class MyAspect {
public void before(){
System.out.println("前置通知");
}
}
- applicationContext2.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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 定义被增强的类 -->
<bean id="productDAO" class="cn.demo2.ProductDAO"/>
<!-- 定义切面 -->
<bean id="myAspect" class="cn.demo2.MyAspect"/>
<!-- 定义AOP的配置 -->
<aop:config>
<!-- 定义切点 -->
<aop:pointcut expression="execution(* cn.demo2.ProductDAO.add(..))" id="pointcut"/>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
</beans>
- 测试类
package cn.demo2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class SpringTest {
@Autowired
@Qualifier("productDAO")
private ProductDAO productDAO;
@Test
public void demo1(){
productDAO.add();
productDAO.delete();
productDAO.find();
productDAO.update();
}
}
1.5 Spring的JDBC Template
1.5.1JDBC Template
- Spring JDBC是Spring提供的持久层技术。
- 简化JDBC API开发,使用上和Apache公司的DButils框架类似。
1.5.2Spring对不同持久层技术的支持
- Spring为各种支持的持久化技术,都提供了简单模板和回调
| ORM持久层技术 | 模板类 |
| JDBC |
org.springframework.jdbc.core.JdbcTemplate |
| Hibernate3.0 |
org.springframework.orm.hibernate3.HibernateTemplate |
|
IBatis(MyBatis) |
org.springframework.orm.ibatis.SqlMapClientTemplate |
|
JPA |
org.springframework.orm.jpa.JpaTemplate |
1.5.3 开发JDBC Template入门
- 引入jar包
- spring-beans-3.2.0.RELEASE.jar
- spring-context-3.2.0.RELEASE.jar
- spring-core-3.2.0.RELEASE.jar
- spring-expression-3.2.0.RELEASE.jar
- com.springsource.org.apache.commons.logging-1.1.1.jar
- com.springsource.org.apache.log4j-1.2.15.jar
- spring-jdbc-3.2.0.RELEASE.jar
- spring-tx-3.2.0.RELEASE.jar
- 数据库驱动
- 创建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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
</beans>
- 测试
package cn.demo1;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class SpringTest {
@Test
public void demo1(){
//创建连接池
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//设置参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring3_day02");
dataSource.setUsername("root");
dataSource.setPassword("root");
//使用JDBC模板
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute("create table user( id int primary key auto_increment,name varchar(20))");
}
}
1.5.4配置连接池
- Spring默认的连接池
- 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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 测试类
package cn.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class SpringTest {
@Test
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.execute("insert into user (name) values ('哈哈')");
}
}
- DBCP连接池
- 导入jar包
- com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
- com.springsource.org.apache.commons.pool-1.5.3.jar
- applicationContext.xml
- 导入jar包
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置DBCP连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 测试类
package cn.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class SpringTest {
@Test
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.execute("insert into user (name) values ('呵呵')");
}
}
- C3p0连接池
- 导入jar包
- com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
- applicationContext.xml
- 导入jar包
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置DBCP连接池 -->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置C3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring3_day02"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 测试类
package cn.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class SpringTest {
@Test
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.execute("insert into user (name) values ('嘻嘻')");
}
}
1.5.5设置参数到属性文件
- 在src下新建了一个jdbc.properties
driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql:///spring3_day02 user=root password=root
- 需要在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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置DBCP连接池 -->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
<!-- 配置C3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"/>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 第二种写法
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置DBCP连接池 -->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean> -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"/>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 测试
package cn.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class SpringTest {
@Test
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
jdbcTemplate.execute("insert into user (name) values ('笨笨')");
}
}
1.5.6JDBC Template的CRUD操作
- 为了方便DAO中注入JdbcTemplate,Spring为每一个持久化技术都提供了支持类。
| ORM持久化技术 | 支持类 |
| JDBC |
org.springframework.jdbc.core.support.JdbcDaoSupport |
| Hibernate3.0 |
org.springframework.orm.hibernate3.support.HibernateDaoSupport |
| iBatis |
org.springframework.orm.ibatis.support.SqlMapClientDaoSupport |
1.5.7JDBC Template的增、删、改操作
- 实体类User
package cn.demo1;
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- UserDAO
package cn.demo1;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class UserDAO extends JdbcDaoSupport{
public void add(User user){
String sql = "insert into user values(null,?)";
this.getJdbcTemplate().update(sql, user.getName());
}
public void update(User user){
String sql = "update user set name = ? where id = ?";
this.getJdbcTemplate().update(sql, user.getName(),user.getId());
}
public void delete(User user){
String sql = "delete from user where id = ?";
this.getJdbcTemplate().update(sql, user.getId());
}
}
- jdbc.properties
driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql:///spring3_day02 user=root password=root
- 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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置Spring默认的连接池 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 配置DBCP连接池 -->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring3_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean> -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"/>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
<!-- 定义JDBC Template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDAO" class="cn.demo1.UserDAO">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
</beans>
- 测试类
package cn.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
@Test
public void demo1(){
User user = new User();
user.setName("哈哈");
userDAO.add(user);
}
@Test
public void demo2(){
User user = new User();
user.setId(1);
user.setName("呵呵");
userDAO.update(user);
}
@Test
public void demo3(){
User user = new User();
user.setId(1);
userDAO.delete(user);
}
}
1.5.8JDBC Template的查询操作
- 简单查询
- select count(*) from user;
- select name from user where id = ?;
public int findCount(){
String sql = "select count(*) from user";
return this.getJdbcTemplate().queryForInt(sql);
}
@Test
public void demo4(){
System.out.println("总共:"+userDAO.findCount());
}
public String findNameById(int id){
String sql = "select name from user where id = ?";
return this.getJdbcTemplate().queryForObject(sql,String.class,id);
}
@Test
public void demo5(){
System.out.println(userDAO.findNameById(1));
}
- 复杂查询:返回对象和对象集合
- select * from user where id = ?;
- select * from user;
public User findById(int id){
String sql = "select * from user where id = ?";
return (User) this.getJdbcTemplate().query(sql,new ResultSetExtractor<User>(){
@Override
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
User user = new User();
if(rs.next()){
user.setId(rs.getInt(1));
user.setName(rs.getString(2));
}
return user;
}
}, id);
}
@Test
public void demo6(){
User user = userDAO.findById(2);
System.out.println(user.getId()+","+user.getName());
}
public List<User> findAll(){
String sql = "select * from user";
return this.getJdbcTemplate().query(sql, new RowMapper<User>(){
@Override
public User mapRow(ResultSet rs, int paramInt) throws SQLException {
User user = new User();
user.setId(rs.getInt(1));
user.setName(rs.getString(2));
return user;
}});
}
@Test
public void demo7(){
List<User> users = userDAO.findAll();
for (User user : users) {
System.out.println(user.getId()+","+user.getName());
}
}
Spring(二)的更多相关文章
- spring(二、bean生命周期、用到的设计模式、常用注解)
spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...
- Spring(二)Bean入门
一.BeanFactory介绍 1.1.Bean: 在Spring技术中是基于组件的 最基本了是最常用的单元 其实实例保存在Spring的容器当中 Bean通常被定义在配置文件当中,Bean实例化由S ...
- Spring(二)——IoC
IoC(Inversion of Control)称之为控制反转,指的是在Spring框架的配置文件中声明对象,由框架负责创建对象,这叫做控制反转.实现方式有两种:DI(Dependency Inje ...
- spring(二) AOP之AspectJ框架的使用
前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...
- Spring(二)之入门示例
任何编程技术,特别是入门示例,通常都是Hello World,在这里我也遵循这个业界公认的原则. 这里我使用的maven项目,大家如果想要演示,建议使用Eclipse(含maven插件)或Idea(含 ...
- Spring(二十)之使用Log4j记录日志
日志记录,也是常用的,比如异常信息记录或者其他相关信息记录,良好的日志记录有助于当系统出现某些不是特别大的问题时,可及时通过日志信息,捕捉到异常,从而确定是那段代码的问题,避免影响其他的代码. 关于m ...
- Spring(二) -- 春风拂面之 核心 AOP
”万物皆对象“是面向对象编程思想OOP(Object Oriented Programming) 的最高境界.在面向对象中,我一直将自己(开发者)放在一个至高无上的位置上,可以操纵万物(对象),犹如一 ...
- Spring(二)--IoC&AOP
IOC 一.IOC概述: 一般指控制反转(inversion of Control),把创建对象的权利交给框架,Ioc容器控制对象,是框架的重要特征,并非是面向对象编程的专用术语.它包括依赖注入(DI ...
- Spring(二)scope、集合注入、自动装配、生命周期
原文链接:http://www.orlion.ga/189/ 一.scope bean的scope属性中常用的有两种:singleton(单例,默认)和prototype(原型,每次创建新对象) 例: ...
- 学习Spring(二) 调用静态工厂方法创建Bean
1,创建抽象的产品类 package com.robert.spring.shop; public abstract class Product { } 2,创建具体产品类 package com.r ...
随机推荐
- Java基础(1) - 语法 & 概念
Java基础语法 基础 1. Java对大小写敏感 2. Java注释 //单行注释 这是一行注释 /* 这里是多行 注释 */ /** 这里是文档注释 @author 0o晓月メ */ 3. 访问修 ...
- angularJS 源码阅读之一:toDebugString
简介: 这个函数返回调试字符串: number,boolean,string,null,undefined,都会转为字符串. function 中括号前面有空格的,会去除函数体,没空格的,会输出函数的 ...
- Vijos 1012 清帝之惑之雍正 平面最近点对(分治)
背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...
- 极客圈(一)树莓派3B协同Python打造个性化天气闹钟
人生苦短,我用Python~ 一直想自己折腾些极客的东西出来,供自己使用或者是供他人使用.一则可能对自己的生活是一种帮助,二则是对自己技能的提高,三则显得高大上,一直努力,一直提高,一直Happy!~ ...
- Educational Codeforces Round 20.C
C. Maximal GCD time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- [基础架构]PeopleSoft Application Server 重要文件说明
我们都知道PeopleSoft是由几个不同的服务组成的,他们在PeopleSoft体系结构中扮演着自己的角色.这些服务具有不同的文件结构并包含重要的可执行文件和配置文件. 以下是Peoplesoft体 ...
- 元组-tuple功能介绍
#元组 不可变类型 相当于只读的列表,不可被修改,不可被修改哦 ##创建元组最后加,最后加, 形成良好的习惯 """ tuple() -> empty tuple ...
- linux中日志介绍
linux日志 linux日志大多是以明文存储,一般存储在/var/log目录中,linux系统中主要有三个日志子系统:连接时间日志,进程统计日志,错误日志. 连接时间日志 连接时间日志是有多个程序执 ...
- CJOJ 2044 【一本通】最长公共子序列(动态规划)
CJOJ 2044 [一本通]最长公共子序列(动态规划) Description 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X,则另一序列Z是X的子序列是指存在一个 ...
- java 笔记 Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()区别
查了一些资料也不是太明白两个的区别,但是前者是最安全的用法 打个简单的比方,你一个WEB程序,发布到Tomcat里面运行.首先是执行Tomcat org.apache.catalina.startup ...