Java 框架 03 — Spring_03(AOP演示_xml配置_注解配置、Spring整合JDBC、JdbcDaoSupport)

一、AOP演示

1.1 xml配置文件

1.1.1 导包

  • 4 + 2 + 4
    • 最后一个4
      • Spring的AOP包
        1. spring-aspects-4.2.4.RELEASE.jar
        2. spring-aop-4.2.4.RELEASE.jar
      • Spring需要的第三方AOP包
        1. com.springsource.org.aopalliance-1.0.0.jar
        2. com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

1.1.2 准备目标对象

package a_springaop;

// 切入点的类
public class UserServiceImpl implements UserService {

	@Override
	public void add() {
//		异常
		int a = 1/0;
		System.out.println("add");
	}

	@Override
	public void delete() {
		System.out.println("delete");
	}

	@Override
	public void modify() {
		System.out.println("modify");
	}

	@Override
	public void find() {
		System.out.println("find");
	}
}

1.1.3 准备通知

  1. 前置通知:在切入点之前执行
  2. 后置通知:在切入点之后执行(无论有没有异常都执行)
  3. 环绕通知:切入点之前和之后都执行;如果遇到异常,之后的代码就不执行
  4. 异常通知:在切入点遇到异常后执行
  5. 后置通知:在切入点正常结束后才执行
package a_springaop;

import org.aspectj.lang.ProceedingJoinPoint;

// 通知类 - 基本了解
// 前置通知
	// -在切入点之前执行
// 后置通知
	// -在切入点之后执行(无论有没有异常都执行)
// 环绕通知 ProceedingJoinPoint
	// 切入点之前和之后都执行
	// 如果遇到异常,之后的代码就不执行
// 异常通知
	// 在切入点遇到异常后执行
// 后置通知 afterReturning
	// 在切入点正常结束后才执行
public class MyAdvice {
	// 前置通知
	public void before() {
		System.out.println("前置通知");
	}
	public void after() {
		System.out.println("后置通知1");
	}
	public void around(ProceedingJoinPoint jp) throws Throwable {
		System.out.println("环绕通知前");
		// 执行原来方法
		jp.proceed();
		System.out.println("环绕通知后");
	}
	public void afterException() {
		System.out.println("异常通知");
	}
	public void afterReturnning() {
		System.out.println("后置通知2");
	}
}

1.1.4 将通知织入到目标对象中

  1. 配置切入点
  2. 配置通知类
  3. 织入:添加新的命名空间:aop
    1. aop:config
      1. 切入点配置:aop:pointcut
        1. 配置方法:expressionexpression="execution(* a_springaop.*ServiceImpl.*(..))"
        2. 切入点id:id
      2. 配置切面:aop:aspect
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	
	<!-- 1.配置切入点类 -->
	<bean name="userService" class="a_springaop.UserServiceImpl"></bean>
	<!-- 2.配置通知类 -->
	<bean name="myAdvice" class="a_springaop.MyAdvice"></bean>
	
	<!-- 3.织入 添加新的命名空间:aop -->
	<aop:config>
		<!-- 切入点配置:要增强的方法
				void a_springaop.UserServiceImpl.add()
				* a_springaop.UserServiceImpl.add()
				* a_springaop.UserServiceImpl.*()
				* a_springaop.*ServiceImpl.*()
				* a_springaop.*ServiceImpl.*(..)
		 -->
		<aop:pointcut expression="execution(* a_springaop.*ServiceImpl.*(..))" id="pc"/>
		<!-- 配置切面 -->
		<aop:aspect ref="myAdvice">
			<aop:before method="before" pointcut-ref="pc"/>
			<aop:after method="after" pointcut-ref="pc"/>
			<aop:around method="around" pointcut-ref="pc"/>
			<aop:after-throwing method="afterException" pointcut-ref="pc"/>
			<aop:after-returning method="afterReturnning" pointcut-ref="pc"/>
		</aop:aspect>
	</aop:config>
</beans>

1.2 注解配置

1.2.1 导包(与配置文件一致)

1.2.2 准备目标对象(与配置文件一致)

1.2.3 准备通知(一定要在配置文件中开启注解)

  • 使用注解之前,配置文件中开启注解
    • <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
// 通知类 - 基本了解
// 前置通知
	// -在切入点之前执行
// 后置通知
	// -在切入点之后执行(无论有没有异常都执行)
// 环绕通知 ProceedingJoinPoint
	// 切入点之前和之后都执行
	// 如果遇到异常,之后的代码就不执行
// 异常通知
	// 在切入点遇到异常后执行
// 后置通知 afterReturning
	// 在切入点正常结束后才执行
// 使用注解之前,配置文件中开启注解
// <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:p="http://www.springframework.org/schema/p"
    	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-4.3.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    	
    	<!-- 1.配置切入点类 -->
    	<bean name="userService" class="b_annotationaop.UserServiceImpl"></bean>
    	<!-- 2.配置通知类 -->
    	<bean name="myAdvice" class="b_annotationaop.MyAdvice"></bean>
    	<!-- 3.使用注解配置织入过程 -->
    	<!-- 开启aop的注解配置 -->
    	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    </beans>
    

1.2.4 将通知织入目标对象中

package b_annotationaop;

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;

// 通知类 - 基本了解
// 前置通知
	// -在切入点之前执行
// 后置通知
	// -在切入点之后执行(无论有没有异常都执行)
// 环绕通知 ProceedingJoinPoint
	// 切入点之前和之后都执行
	// 如果遇到异常,之后的代码就不执行
// 异常通知
	// 在切入点遇到异常后执行
// 后置通知 afterReturning
	// 在切入点正常结束后才执行
// 使用注解之前,配置文件中开启注解
// <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect // 标志类是通知类
public class MyAdvice {
	@Pointcut("execution(* b_annotationaop.*ServiceImpl.*(..))")
	public void pc() {
		// 方法唯一的用处就是为了承载注解
	}
	// 前置通知
	@Before("MyAdvice.pc()")
	public void before() {
		System.out.println("前置通知");
	}
	@After("MyAdvice.pc()")
	public void after() {
		System.out.println("后置通知1");
	}
	@Around("execution(* b_annotationaop.*ServiceImpl.*(..))")
	public void around(ProceedingJoinPoint jp) throws Throwable {
		System.out.println("环绕通知前");
		// 执行原来方法
		jp.proceed();
		System.out.println("环绕通知后");
	}
	@AfterThrowing("execution(* b_annotationaop.*ServiceImpl.*(..))")
	public void afterException() {
		System.out.println("异常通知");
	}
	@AfterReturning("execution(* b_annotationaop.*ServiceImpl.*(..))")
	public void afterReturnning() {
		System.out.println("后置通知2");
	}
}

二、Spring整合JDBC

2.1 Spring提供的DAO层模板

在这里插入图片描述

2.2 JdbcTemplate

  • 功能与DBUtilsQueryRunner类似

    //0. 准备连接池
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql:///ssh");
    dataSource.setUser("root");
    dataSource.setPassword("root");
    
    //1. 创建JDBC模板对象
    JdbcTemplate jt = new JdbcTemplate();
    jt.setDataSource(dataSource);
    
    //2. 书写sql,并执行
    String sql = "insert into user values(null, 'rose')";
    jt.update(sql);
    

2.3 步骤

2.3.1 导包

  1. 4 + 2:4个核心+2个日志
  2. 测试和切面需要的
    1. spring-test
    2. spring-aop
    3. junit4类库
  3. 数据库
    1. c3p0连接池
    2. JDBC驱动
  4. 事务
    1. spring-jdbc
    2. spring-tx事务

2.3.2 准备数据库

在这里插入图片描述

2.3.3 书写DAO

package c_jdbctemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;


public class UserDaoImpl implements UserDao {
	private JdbcTemplate jdbcTemplate;
	//增
	@Override
	public void addUser(User user) {
		String sql = "insert into user values(null,?)";
		jdbcTemplate.update(sql, user.getName());
	}
	//删
	@Override
	public void deleteUserById(int id) {
		String sql = "delete from user where id = ?";
		jdbcTemplate.update(sql, id);
	}
	//改
	@Override
	public void updateUser(User user) {
		String sql = "update user where id=? and name=?";
		jdbcTemplate.update(sql, user.getId(), user.getName());
	}
	//查全部
	@Override
	public List<User> findAll() {
		String sql = "select * from user";
		List<User> list = jdbcTemplate.query(sql, new RowMapper<User>() {

			@Override
			public User mapRow(ResultSet rs, int index) throws SQLException {
				int id = rs.getInt("id");
				String name = rs.getString("name");
				User user = new User();
				user.setId(id);
				user.setName(name);
				return user;
			}
			
		});
		return list;
	}
	//查单个
	@Override
	public User getUser(int id) {
		String sql = "select * from user where id = ?";
		
		User user = jdbcTemplate.queryForObject(sql, new RowMapper<User>() {

			@Override
			public User mapRow(ResultSet rs, int index) throws SQLException {
				int id1 = rs.getInt("id");
				String name1 = rs.getString("name");
				User user = new User();
				user.setId(id1);
				user.setName(name1);
				return user;
			}
			
		}, id);
		return user;
	}
	
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
}

2.3.4 Spring配置

  • 逐层注入原理

在这里插入图片描述

  • 因此要在配置文件中,都要注入。需要什么,注入什么

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:p="http://www.springframework.org/schema/p"
    	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-4.3.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    	
    	<!-- 注册Dao -->
    	<bean name="userDao" class="c_jdbctemplate.UserDaoImpl">
    		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
    	</bean>
    	<!-- 注册jdbcTemplate -->
    	<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<!-- 注册DataSource -->
    	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    		<property name="jdbcUrl" value="jdbc:mysql:///ssh"></property>
    		<property name="user" value="root"></property>
    		<property name="password" value="123456"></property>
    	</bean>
    </beans>
    

2.3.5 测试

package c_jdbctemplate;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:c_jdbctemplate/applicationContext.xml")
public class JdbcTemplateDemo {
	@Autowired
	private UserDao ud;
	@Test
	public void test01() {
		User user = new User();
		user.setName("lucy");
		ud.addUser(user);
	}
	
	@Test
	public void test02() {
		User user = ud.findUserById(1);
		System.out.println(user);
	}
    
	@Test
	public void test03() {
		List<User> list = ud.findAll();
		System.out.println(list);
	}
}

2.4 进阶内容(JdbcDaoSupport)

2.4.1 原理

  • JdbcTemplate的注入交给别人(JdbcDaoSupport)来做,注入过程少了一个步骤

在这里插入图片描述

  • AccountDaoImpl:继承JdbcDaoSupport

    package d_transaction;
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    // JdbcDaoSupport已经包含了 JdbcTemplate
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    	
    	@Override
    	public void decrement(int fromId, double money) {
    		String sql = "update account set money = money - ? where id = ?";
    		// 调用父类的JdbcTemplate对象
    		getJdbcTemplate().update(sql, money, fromId);
    	}
    
    	@Override
    	public void increment(int toId, double money) {
    		String sql = "update account set money = money + ? where id = ?";
    		getJdbcTemplate().update(sql, money, toId);
    	}
    }
    
  • 配置文件中进行注册

    	<!-- 1.注册service -->
    	<bean name="accountService" class="d_transaction.AccountServiceImpl" >
    		<property name="ad" ref="accountDao"></property>
    	</bean>
    	
    	<!-- 2.注册dao -->
    	<bean name="accountDao" class="d_transaction.AccountDaoImpl">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	
    	<!-- 4.注册dataSource -->
    	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    		<property name="jdbcUrl" value="jdbc:mysql:///ssh"></property>
    		<property name="user" value="root"></property>
    		<property name="password" value="123456"></property>
    	</bean>
    

2.4.1 读取外部的Properties配置

  • 外部配置文件:db.properties

    jdbc.driverClass=com.mysql.jdbc.Driver
    jdbc.jdbcUrl=jdbc:mysql:///ssh
    jdbc.user=root
    jdbc.password=root
    
  • 配置文件中注意加前缀context:

    	<!-- 1.引入src/db.properties配置文件 -->
    	<context:property-placeholder location="classpath:db.properties"/>
    	<!-- 3.注册dataSource -->
    	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="driverClass" value="${jdbc.driverClass}"></property>
    		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    		<property name="user" value="root"></property>
    		<property name="password" value="123456"></property>
    	</bean>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值