1. 回顧
線程死鎖概念和如何避免死鎖的發(fā)生:
線程的通信 wait notify() notify():---Object類
線程的狀態(tài): NEW--->start()--->就緒狀態(tài)---CPU時間片---運行狀態(tài)RUNNABLE]--->sleep()--->TIMED_WAITING--->wait()---->WAITING----sysn---Blocked---->終止?fàn)顟B(tài)[T]
線程池: 常見的線程池種類: 4種和原始
2. 正文 (3W+1H what why where How)
1. 什么是AOP?
2. 為什么使用AOP?
3. 如何使用AOP?
4. 什么是事務(wù)?
5. spring如何實現(xiàn)事務(wù)管理。
3. 什么是AOP?
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運行期間動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
AOP:它是面向切面編程的語言,它可以讓你的業(yè)務(wù)代碼和非業(yè)務(wù)代碼進行隔離。在不改變業(yè)務(wù)代碼的前提下,可以增加新的非業(yè)務(wù)代碼。
4. 為什么使用AOP
5. AOP應(yīng)用場景
- 記錄日志
- 權(quán)限校驗
- spring事務(wù)管理。
6. AOP的結(jié)構(gòu)
AOP要做的三件事在哪里切入,也就是權(quán)限校驗,等非業(yè)務(wù)操作在哪些業(yè)務(wù) 代碼中執(zhí)行;什么時候切入,是業(yè)務(wù)代碼執(zhí)行前還是執(zhí)行后;切入后做什 么事,比如做權(quán)限校驗、日志記錄等。
- Aspect: 切面
- PointCut:切點:---方式: 路徑表達式 (2)注解形式
- Advice: 處理的時機。
7. 如何使用AOP
案例
public class MathServiceImpl implements MathService {
public double add(double a, double b) {
double result=a+b;
System.out.println("AAA--->The add method result="+result);
return result;
}
public double mul(double a, double b) {
double result=a-b;
System.out.println("AAA--->The mul method result="+result);
return result;
}
public double cheng(double a, double b) {
double result=a*b;
System.out.println("AAA--->The cheng method result="+result);
return result;
}
public double div(double a, double b) {
double result=a/b;
System.out.println("AAA--->The div method result="+result);
return result;
}
}
發(fā)現(xiàn): 我們在每個操作后,都要記錄日志,如果后期日志內(nèi)容發(fā)生改變。需要在每個操作后都進行修改。 不利于代碼的維護。
我們來使用AOP來解決。
(1)引入相關(guān)依賴
<dependencies>
<!--引入spring核心依賴庫-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--引入spring切面依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
</dependencies>
(2)創(chuàng)建一個切面類
@Aspect //標(biāo)記該類為切面類
@Component //該類對象的創(chuàng)建交于spring容器來管理-----等價于@Service @Controller
public class MyAspect {
@Pointcut(value = "execution(public double com.ykq.aop.MathServiceImpl.add(double, double))") //定義為切點
private void mypointcut(){}
@After(value = "mypointcut()")
public void b(){
System.out.println("AAA--->The add method result");
}
}
(3) 創(chuàng)建一個spring配置文件
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--包掃描-->
<context:component-scan base-package="com.ykq.aop"/>
<!--開啟aop切面注解驅(qū)動-->
<aop:aspectj-autoproxy/>
</beans>
(4)測試
public class Test {
public static void main(String[] args) {
//加載spring配置文件
ApplicationContext app=new ClassPathXmlApplicationContext("classpath:spring.xml");
MathService mathServiceImpl = (MathService) app.getBean("mathServiceImpl");
System.out.println(mathServiceImpl.add(20, 10));
}
}
使用通配符來統(tǒng)配類路徑
@Aspect //標(biāo)記該類為切面類
@Component //該類對象的創(chuàng)建交于spring容器來管理-----等價于@Service @Controller
public class MyAspect {
//通配符:
/**
* 第一個* : 表示任意修飾符 任意返回類型。
* 第二個* : 表示該包下所有的類。
* 第三個* : 類下所有的方法
* ..: 表示任意參數(shù)
*
* 建議包就別使用統(tǒng)配符
*/
@Pointcut(value = "execution(* com.ykq.aop.*.*(..))") //定義為切點
private void mypointcut(){}
@After(value = "mypointcut()")
public void b(){
System.out.println("AAA--->The add method result");
}
}
7.2 注解模式
(1)自定義注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
(2)修改切面類
@Pointcut(value = "@annotation(com.ykq.aop.MyAnnotation)") //定義為切點
private void mypointcut2(){}
//在使用MyAnntation注解的方法之后執(zhí)行內(nèi)容
@After(value = "mypointcut2()")
public void b(){
System.out.println("AAA--->The add method result");
}
7.3 aop切面通知的類型
package com.aaa.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect //標(biāo)記該類為切面類
@Component //該類對象的創(chuàng)建交于spring容器來管理-----等價于@Service @Controller
public class MyAspect {
//通配符:
/**
* 第一個* : 表示任意修飾符 任意返回類型。
* 第二個* : 表示該包下所有的類。
* 第三個* : 類下所有的方法
* ..: 表示任意參數(shù)
*
* 建議包就別使用統(tǒng)配符
*/
@Pointcut(value = "execution(* com.ykq.aop.*.*(..))") //定義為切點
private void mypointcut(){}
@Pointcut(value = "@annotation(com.ykq.aop.MyAnnotation)") //定義為切點
private void mypointcut2(){}
// //在使用MyAnntation注解的方法之后執(zhí)行內(nèi)容。無論如何都執(zhí)行。
// @After(value = "mypointcut()")
// public void a(){
// System.out.println("AAA--->The add method result");
// }
//
// //前置通知:
// @Before(value = "mypointcut()")
// public void b(){
// System.out.println("========方法執(zhí)行前執(zhí)行切面的內(nèi)容 前置通知===========");
// }
//
// //后置返回通知. 碰到return. 如果方法出現(xiàn)異常;這種通知不會被執(zhí)行
// @AfterReturning(value = "mypointcut()",returning = "r") //returnning它會把方法執(zhí)行的結(jié)果賦值給該變量
// public void afterReturning(Object r){ //參數(shù)名必須和returning的名稱一致
// System.out.println("~~~~~~~~~~~~~~~~~~后置返回通知~~~~~~~~~~~~~~~~"+r);
// }
//
// //異常通知: 當(dāng)被切入的方法出現(xiàn)異常時,才會執(zhí)行
// @AfterThrowing(value = "mypointcut()")
// public void afterThrowable(){
// System.out.println("==============異常通知===========================");
// }
//環(huán)繞通知。
@Around(value = "mypointcut()")
public Object around(ProceedingJoinPoint joinPoint){//joinPoint:連接點 理解為被執(zhí)行的方法對象
System.out.println("業(yè)務(wù)代碼執(zhí)行前執(zhí)行的內(nèi)容======================");
try {
Object result = joinPoint.proceed();//執(zhí)行你的連接點
System.out.println("方法執(zhí)行完畢后~~~~~~~~~~~~~~~~~");
return result;
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("方法出現(xiàn)異常時執(zhí)行~~~~~~~~~~~~~");
}finally{
System.out.println("無論如何都會執(zhí)行");
}
return 0.0;
}
}
@Before 前置通知. 被代理的方法執(zhí)行前--執(zhí)行
@After: 后置通知: 被代理的方法執(zhí)行完后--執(zhí)行
@AfterReturning: 后置返回通知: 被代理的方法碰到return.--才會執(zhí)行
@AfterThrowing: 后置異常通知: 當(dāng)被代理的方法出現(xiàn)異常時--才會執(zhí)行。
@Around: 環(huán)繞通知。
8. spring如何操作事務(wù)
8.1 什么是事務(wù)?
事務(wù)就是一系列的動作, 它們被當(dāng)做一個單獨的工作單元. 這些動作要么全部完成, 要么全部不起作用.
例子: 轉(zhuǎn)賬
扣錢和加錢----要么都執(zhí)行要么都不執(zhí)行。
JDBC----它模式事務(wù)自動提交的。
public class Test {
public static void main(String[] args) {
Connection conn=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/aaa?serverTimezone=Asia/Shanghai","root","root");
conn.setAutoCommit(false);//設(shè)置事務(wù)手動提交。
PreparedStatement ps=conn.prepareStatement("update t_user set balance=balance-600 where id=7");
ps.executeUpdate();
//int i=10/0;
PreparedStatement ps2=conn.prepareStatement("update t_user set balance=balance+600 where id=6");
ps2.executeUpdate();
conn.commit();//事務(wù)提交
}catch (Exception e){
e.printStackTrace();
//事務(wù)回滾
try {
conn.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}finally {
}
}
}
8.2 spring如何實現(xiàn)事務(wù)
spring框架一定會提供一個事務(wù)切面類。【1】前置通知---開啟手動事務(wù) [2]后置返回通知[事務(wù)提交] [3]異常通知[事務(wù)回滾]
(1)依賴
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--spring事務(wù)依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
<!--mybatis的依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!--mybatis和spring整合的依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!--druid的連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
(2)spring配置文件
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--springmvc的配置-->
<context:component-scan base-package="com.ddd"/>
<!--spring整合mybatis的配置-->
<!--數(shù)據(jù)源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<!--mysql驅(qū)動為8.0以后必須使用時區(qū)-->
<property name="url" value="jdbc:mysql://localhost:3306/aaa?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--spring封裝了一個類SqlSessionFactoryBean類,可以把mybatis中的配置-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:/mapper/*.xml"/>
</bean>
<!--為指定dao包下的接口生產(chǎn)代理實現(xiàn)類-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
<!--它會為com.ykq.dao包下的所有接口生產(chǎn)代理實現(xiàn)類-->
<property name="basePackage" value="com.ddd.dao"/>
</bean>
<!----================以下內(nèi)容是關(guān)于事務(wù)的配置===================------>
<!--事務(wù)切面管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--開啟事務(wù)管理注解的驅(qū)動-->
<tx:annotation-driven/>
</beans>
(3) dao類和xml
public interface UserDao {
//1.修改賬號余額
public void updateBalance(@Param("id") int id, @Param("money") double money);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace必須和dao接口的名稱一模一樣-->
<mapper namespace="com.ddd.dao.UserDao">
<update id="updateBalance">
update t_user set balance=balance+#{money} where id=#{id}
</update>
</mapper>
(4)service文章來源:http://www.zghlxwxcb.cn/news/detail-652457.html
package com.ddd.service.impl;
import com.ddd.dao.UserDao;
import com.ddd.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserServieImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional //該方法交于spring的事務(wù)來管理了---默認spring不識別該注解
public void zhuanzhang(int id, int uid, double money) {
//1.扣錢
userDao.updateBalance(id,-money);
//int c=10/0;
//2.收錢
userDao.updateBalance(uid,money);
}
}
(5)測試:文章來源地址http://www.zghlxwxcb.cn/news/detail-652457.html
public class Test {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("classpath:spring.xml");
UserService userServieImpl = (UserService) app.getBean("userServieImpl");
userServieImpl.zhuanzhang(7,6,400);
}
}
到了這里,關(guān)于java Sping aop 以及Spring aop 的應(yīng)用事務(wù)管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!