三 AOP
设置切面优先级
代码部分
项目结构:
基于注解的AOP:
spring.aop.annotation.LoggingAspect
//可以通过@order注解的value属性设置切面的优先级,默认值是int的最大值,值越小优先级越高
@Order(5) //多个切面时,相同通知的执行优先级设置,数字越大,相应切面的通知优先级越高
@Component //交给spring管理
@Aspect //切面类
public class LoggingAspect {
//声明切入点表达式
@Pointcut(value = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))")
public void pointCut(){
}
/*
切入点表达式的表示方式
1.execution(public int com.atguigu.spring.aop.beans.Calculator.add(int ,int ))
-在com.atguigu.spring.aop.beans.Calculator接口中add方法执行
2.execution(public int com.atguigu.spring.aop.beans.Calculator.*(int ,int ))
-在com.atguigu.spring.aop.beans.Calculator接口中所有方法执行
3.execution(public int Calculator.*(int ,int ))
-在同一个包下Calculator接口中所有方法执行
4.execution(* com.atguigu.spring.aop.beans.Calculator.*(int ,int ))
-不考虑权限修饰符和返回值类型 在com.atguigu.spring.aop.beans.Calculator接口中所有方法执行
5.execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))
-不考虑权限修饰符和返回值类型以及参数的类型和个数 在com.atguigu.spring.aop.beans.Calculator接口中所有方法执行
6.execution(* *.*(.. ))
-不考虑权限修饰符和返回值类型以及参数的类型和个数 在所有接口中所有方法执行
*/
//前置通知 方法执行之前执行
@Before(value = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))")
public void beforAdvice(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("Logging: The method "+methodName+" begins with "+ Arrays.toString(args));
}
//后置通知 方法执行之后执行 无论是否出现异常
@After(value = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))")
public void afterAdvice(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" ends ");
}
//返回通知,在方法返回结果之后执行
//设置的returning的值一定要与传入的形参名字一致
@AfterReturning(pointcut = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))",returning = "result")
public void afterReturnning(JoinPoint joinPoint,Object result){
//获取方法名
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" returns "+result);
}
//异常通知,当方法执行出现异常时执行
//设置throwing的值一定要与传入的形参名字一致
@AfterThrowing(pointcut = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
//获取方法名
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" throwing "+e);
}
//环绕通知 相当于动态代理的全过程
@Around(value = "execution(* com.atguigu.spring.aop.beans.Calculator.*(.. ))")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] args = proceedingJoinPoint.getArgs();
Object result=null;
try {
//前置通知
System.out.println("@Logging: The method "+methodName+" begins with "+ Arrays.toString(args));
//执行目标方法
result = proceedingJoinPoint.proceed();
//返回通知
System.out.println("@Logging: The method "+methodName+" returns "+result);
} catch (Throwable throwable) {
//异常通知
System.out.println("@Logging: The method "+methodName+" throwing "+throwable);
throwable.printStackTrace();
}finally {
//后置通知
System.out.println("@Logging: The method "+methodName+" ends ");
}
return result;
}
}
spring.aop.beans.Calculator
public interface Calculator {
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
}
spring.aop.beans.CalculatorImpl
@Component("calculator")
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
int result = a+b;
return result;
}
@Override
public int sub(int a, int b) {
int result = a-b;
return result;
}
@Override
public int mul(int a, int b) {
int result = a*b;
return result;
}
@Override
public int div(int a, int b) {
int result = a/b;
return result;
}
}
spring.aop.test.AOPTest
public class AOPTest {
ApplicationContext ioc=new ClassPathXmlApplicationContext("beans-aop.xml");
@Test
public void testAOP(){
Calculator calculator =(Calculator) ioc.getBean("calculator");
int add = calculator.add(1, 2);
System.out.println(add);
int sub = calculator.sub(5, 6);
System.out.println(sub);
int mul = calculator.mul(4, 5);
System.out.println(mul);
int div = calculator.div(5, 0);
System.out.println(div);
}
}
/*
@Logging: The method add begins with [1, 2]
Logging: The method add begins with [1, 2]
Logging: The method add returns 3
Logging: The method add ends
@Logging: The method add returns 3
@Logging: The method add ends
3
@Logging: The method sub begins with [5, 6]
Logging: The method sub begins with [5, 6]
Logging: The method sub returns -1
Logging: The method sub ends
@Logging: The method sub returns -1
@Logging: The method sub ends
-1
@Logging: The method mul begins with [4, 5]
Logging: The method mul begins with [4, 5]
Logging: The method mul returns 20
Logging: The method mul ends
@Logging: The method mul returns 20
@Logging: The method mul ends
20
@Logging: The method div begins with [5, 0]
Logging: The method div begins with [5, 0]
Logging: The method div throwing java.lang.ArithmeticException: / by zero
Logging: The method div ends
@Logging: The method div throwing java.lang.ArithmeticException: / by zero
*/
beans-aop.xml
<!-- 自动扫描包-->
<c:component-scan base-package="com.atguigu.spring.aop"/>
<!-- 添加aspect注解支持-->
<a:aspectj-autoproxy/>
基于XML配置文件的AOP:
spring.aop.xml.Calculator
spring.aop.xml.CalculatorImpl
public interface Calculator {
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
}
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
int result = a+b;
return result;
}
@Override
public int sub(int a, int b) {
int result = a-b;
return result;
}
@Override
public int mul(int a, int b) {
int result = a*b;
return result;
}
@Override
public int div(int a, int b) {
int result = a/b;
return result;
}
}
spring.aop.xml.LoggingAspect
public class LoggingAspect {
//前置通知 方法执行之前执行
public void beforAdvice(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("Logging: The method "+methodName+" begins with "+ Arrays.toString(args));
}
//后置通知 方法执行之后执行 无论是否出现异常
public void afterAdvice(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" ends ");
}
//返回通知,在方法返回结果之后执行
//设置的returning的值一定要与传入的形参名字一致
public void afterReturnning(JoinPoint joinPoint,Object result){
//获取方法名
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" returns "+result);
}
//异常通知,当方法执行出现异常时执行
//设置throwing的值一定要与传入的形参名字一致
public void afterThrowing(JoinPoint joinPoint,Exception e){
//获取方法名
String methodName = joinPoint.getSignature().getName();
System.out.println("Logging: The method "+methodName+" throwing "+e);
}
//环绕通知 相当于动态代理的全过程
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] args = proceedingJoinPoint.getArgs();
Object result=null;
try {
//前置通知
System.out.println("@Logging: The method "+methodName+" begins with "+ Arrays.toString(args));
//执行目标方法
result = proceedingJoinPoint.proceed();
//返回通知
System.out.println("@Logging: The method "+methodName+" returns "+result);
} catch (Throwable throwable) {
//异常通知
System.out.println("@Logging: The method "+methodName+" throwing "+throwable);
throwable.printStackTrace();
}finally {
//后置通知
System.out.println("@Logging: The method "+methodName+" ends ");
}
return result;
}
}
spring.aop.test.AOPXMLTest
public class AOPXMLTest {
ApplicationContext ioc=new ClassPathXmlApplicationContext("beans-aop-xml.xml");
/*
测试基于xml的配置AOP
*/
@Test
public void testAOPXML(){
Calculator calculator =(Calculator) ioc.getBean("calculator");
int add = calculator.add(1, 2);
System.out.println(add);
int sub = calculator.sub(5, 6);
System.out.println(sub);
int mul = calculator.mul(4, 5);
System.out.println(mul);
int div = calculator.div(5, 0);
System.out.println(div);
}
}
beans-aop-xml.xml
<!-- 将计算器的实现类交给ioc管理-->
<bean id="calculator" class="com.atguigu.spring.aop.xml.CalculatorImpl"/>
<!-- 配置切面类-->
<bean id="loggingAspect" class="com.atguigu.spring.aop.xml.LoggingAspect"/>
<!-- AOP配置-->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut id="pointCut" expression="execution(* com.atguigu.spring.aop.xml.Calculator.*(..))"/>
<!-- 配置切面-->
<aop:aspect ref="loggingAspect">
<!-- 配置通知方法-->
<!-- 前置通知-->
<aop:before method="beforAdvice" pointcut-ref="pointCut"/>
<!-- 后置通知-->
<aop:after method="afterAdvice" pointcut-ref="pointCut"/>
<!-- 返回通知-->
<aop:after-returning method="afterReturnning" pointcut-ref="pointCut" returning="result"/>
<!-- 异常通知-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointCut" throwing="e"/>
<!-- 环绕通知-->
<aop:around method="aroundAdvice" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
Spring整合JdbcTemplate:
spring.jdbc.beans.Employee
public class Employee {
private Integer id;
private String lastName;
private String salary;
private String email;
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", salary='" + salary + '\'' +
", email='" + email + '\'' +
'}';
}
public Employee() {
}
public Employee(Integer id, String lastName, String salary, String email) {
this.id = id;
this.lastName = lastName;
this.salary = salary;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
spring.jdbc.dao.EmployeeDao
spring.jdbc.dao.impl.EmployeeDaoImpl
public interface EmployeeDao {
//获取所有员工
List<Employee> getEmployee();
}
@Repository("employeeDao")
public class EmployeeDaoImpl implements EmployeeDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Employee> getEmployee() {
String sql="select id,last_name lastName,email,salary from employee";
RowMapper<Employee> rowMapper=new BeanPropertyRowMapper<>(Employee.class);
List<Employee> employees = jdbcTemplate.query(sql, rowMapper);
return employees;
}
}
spring.jdbc.jdbcTemplateTest (常用方法测试)
public class jdbcTemplateTest {
ApplicationContext ioc=new ClassPathXmlApplicationContext("beans-jdbc.xml");
//获取JdbcTemplate对象
JdbcTemplate jdbcTemplate= (JdbcTemplate) ioc.getBean("jdbcTemplate");
/*
测试连接
*/
@Test
public void testConnection() throws SQLException {
DataSource dataSource=ioc.getBean(DataSource.class);
//获取连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
/*
测试通用的增删改方法
调用的时JdbcTemplate的update方法
*/
@Test
public void testUpdate(){
String sql="insert into employee(last_name,salary,email) value(?,?,?)";
//调用jdbcTemplate中的update方法
int update = jdbcTemplate.update(sql, "李彦宏", 9999, "liyanhong@baidu.com");
System.out.println(update);
}
/*
测试批处理方法
调用jdbcTemplate中batchUpdata方法
*/
@Test
public void testBatchUpdaya(){
String sql="insert into employee(last_name,salary,email) value(?,?,?)";
List<Object[]> list=new ArrayList<>();
list.add(new Object[]{"王健林",8888,"wangjianling@wanda.com"});
list.add(new Object[]{"刘强东",9988,"liuqiangdong@atguigu.com"});
list.add(new Object[]{"雷军",6666,"leijun@mi.com"});
int[] ints = jdbcTemplate.batchUpdate(sql, list);
System.out.println(ints);
}
/*
获取单一值
获取单一值或者获取一个对象都是调用jdbcTemplate中的queryForObject方法
*/
@Test
public void testGetSingleValue(){
String sql="select count(*) from employee";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println(count);
}
/*
测试获取一个对象
*/
@Test
public void testGetOne(){
String sql="select id,last_name lastName,email,salary from employee where id = ?";
//创建实现类BeanPropertyRowMapper
RowMapper<Employee> rowMapper=new BeanPropertyRowMapper<>(Employee.class);
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 6);
System.out.println(employee);
}
/*
测试获取所有
调用jdbcTemplate中的query方法
*/
@Test
public void testGetAll(){
String sql="select id,last_name lastName,email,salary from employee";
//创建实现类BeanPropertyRowMapper
RowMapper<Employee> rowMapper=new BeanPropertyRowMapper<>(Employee.class);
List<Employee> employees = jdbcTemplate.query(sql, rowMapper);
for (Employee employee : employees) {
System.out.println(employee);
}
}
/*
测试EmployeeDap中获取所有的方法
*/
@Test
public void testEmployeeDao(){
EmployeeDao employeeDao=(EmployeeDao) ioc.getBean("employeeDao");
List<Employee> employees = employeeDao.getEmployee();
employees.forEach(System.out::println);
}
}
beans-jdbc.xml
<!-- 配置自动扫描的包-->
<c:component-scan base-package="com.atguigu.spring.jdbc"/>
<!-- 引入外部属性文件-->
<c:property-placeholder location="classpath:druid.properties"/>
<!-- 配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="initialSize" value="${jdbc.initialSize}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
</bean>
<!-- 配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 配置数据源属性-->
<property name="dataSource" ref="dataSource"/>
</bean>
druid.properties
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/jdbc_template
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.initialSize=5
jdbc.maxActive=10
lib资源: