<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                AOP: aspect oriented programming 面向切面編程 分布于應用中多處的功能稱為橫切關注點,通過這些橫切關注點在概念上是與應用的業務邏輯相分離的,但其代碼往往直接嵌入在應用的業務邏輯之中。將這些橫切關注點與業務邏輯相分離正是面向切面編程(AOP)所要解決的。切面實現了橫切關注點的模塊化 一句話概括:切面是跟具體業務無關的一類共同功能。 案例一、表演 1. 編寫切面類 ~~~ @Component() public class Audience { // 表演之前 public void takeSeats() { System.out.println("The audience is taking their seats."); } // 表演之前 public void turnOffCellPhones() { System.out.println("The audience is turning off their cellphones"); } // 表演成功之后 public void applaud() { System.out.println("CLAP CLAP CLAP CLAP CLAP"); } // 表演失敗之后 public void demandRefund() { System.out.println("Boo! We want our money back!"); } //表演后(finally) public void comment() { System.out.println("the audience is making comments"); } } ~~~ 2. 編寫被代理類(方法一,被代理類必須實現接口) ~~~ public interface Performer { void perform(); } ~~~ ~~~ @Component() public class Instrumentalist implements Performer { private String song = "my love"; public void perform() { System.out.print("Playing " + song + " : "); } } ~~~ XML配置 aspect: 切面 pointcut:切入點(切面和被代理類的結合) advice:通知(前置通知,后置通知,例外通知,最終通知) ~~~ <aop:config> <aop:aspect ref="audience"><!-- 引用audience Bean --> <!-- 聲明切入點 --> <aop:pointcut id="performance" expression="execution(* com.neuedu.model.aop.*.*(..))" /> <!-- 表演之前 --> <aop:before pointcut-ref="performance" method="takeSeats" /> <aop:before pointcut-ref="performance" method="turnOffCellPhones" /> <!-- 表演之后 --> <aop:after-returning pointcut-ref="performance" method="applaud" /> <!-- 表演失敗之后 --> <aop:after-throwing pointcut-ref="performance" method="demandRefund" /> <aop:after pointcut-ref="performance" method="comment" /> </aop:aspect> </aop:config> ~~~ 編寫測試類 ~~~ ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml"); Performer perfomer = (Performer)application.getBean("instrumentalist"); perfomer.perform(); ~~~ 編寫被代理類(方法二:被代理類不實現接口) 1)這種方法需要額外引入cglib jar(spring4.x,自帶cglib功能,不需要引入) 2)在xml中加入 <aop:aspectj-autoproxy proxy-target-class="true"/> 編寫測試類 ~~~ ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml"); Instrumentalist perfomer = (Instrumentalist)application.getBean("instrumentalist"); perfomer.perform(); ~~~ 案例二、事務處理 使用切面之前 DBUtils類 ~~~ public class DBUtils { private static ThreadLocal<Connection> tl = new ThreadLocal<>(); static { //加載數據庫驅動 try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void beginTransaction() { //1.得到數據庫連接 Connection conn = getConnection(); //2.設置自動提交為false try { conn.setAutoCommit(false); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Connection getConnection() { Connection conn = tl.get(); if(conn==null) { try { conn = DriverManager. getConnection("jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8", "root", "root"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //放在本地線程 tl.set(conn); } return conn; } public static void commit() { //1.得到數據庫連接 Connection conn = getConnection(); //2. 提交 try { conn.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void rollback() { //1.得到數據庫連接 Connection conn = getConnection(); //2. 提交 try { conn.rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void close() { //1.得到數據庫連接 Connection conn = getConnection(); //2. 提交 try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //3.把conn從tl中移除 tl.remove(); } } ~~~ Service類 ~~~ @Service public class AccountService { @Autowired AccountDAO accountDAO; public void transferMoney() { //1. 獲得數據庫連接,開啟事務 DBUtils.beginTransaction(); try { accountDAO.deduct(); accountDAO.add(); DBUtils.commit(); } catch(Exception e) { DBUtils.rollback(); e.printStackTrace(); } finally { DBUtils.close(); } } public static void main(String[] args) { //1. 開啟spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); AccountService accountService = (AccountService)context.getBean("accountService"); accountService.transferMoney(); } } ~~~ DAO類 ~~~ @Repository public class AccountDAO { public void deduct() throws SQLException { //1. 獲得連接 Connection conn = DBUtils.getConnection(); PreparedStatement ps = conn.prepareStatement("update account set balance = balance-10 where accountid =2"); ps.executeUpdate(); } public void add() throws SQLException { //1. 獲得連接 Connection conn = DBUtils.getConnection(); PreparedStatement ps = conn.prepareStatement("update account set balance = balance+10 where accountid =1"); ps.executeUpdate(); } } ~~~ 使用切面之后: 切面類 ~~~ public TransactionManagerAspect { public void before() { //1. 獲取數據庫連接 Connection conn = DriverManager.getConnection(); //把conn放在本地線程中 } public void afterreturning() { //從本地線程獲取當前connection //提交事務 conn.commit(); } public void afterthrowing() { //從本地線程獲取當前connection conn.rollback(); } public void finally() { //從本地線程獲取當前connection conn.close(); } } ~~~ Service類 ~~~ class MyService { public void test() { MyDAO myDAO = new MyDAO(); myDAO.deduct(); myDAO.add(); } } ~~~ DAO類實現不變 XML AOP配置 ~~~ <aop:config> <aop:aspect ref="transactionAspect"> <aop:pointcut expression="execution(* com.neuedu.model.service.AccountService2.*(..))" id="transactionpointcut"/> <aop:before method="before" pointcut-ref="transactionpointcut"/> <aop:after-returning method="afterReturning" pointcut-ref="transactionpointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="transactionpointcut"/> <aop:after method="after" pointcut-ref="transactionpointcut"/> </aop:aspect> </aop:config> ~~~ 環繞通知 案例一、表演 ~~~ @Component public class AroundAudience { public void watchPerformance(ProceedingJoinPoint joinpoint) { try { // 表演之前 System.out.println("The audience is taking their seats."); System.out.println("The audience is turning off their cellphones"); long start = System.currentTimeMillis(); // 執行被通知的方法 joinpoint.proceed(); // 表演之后 long end = System.currentTimeMillis(); System.out.println("CLAP CLAP CLAP CLAP CLAP"); System.out.println("The performance took " + (end - start) + " milliseconds."); } catch (Throwable t) { // 表演失敗之后 System.out.println("Boo! We want our money back!"); } finally { System.out.println("leave.."); } } } ~~~ ~~~ <aop:config> <aop:aspect ref="aroundAudience"> <aop:pointcut id="performance" expression="execution(* com.neuedu.model.aop.*.*(..))" /> <aop:around method="watchPerformance" pointcut-ref="performance"/> </aop:aspect> </aop:config> ~~~ 案例二、日志 ~~~ @Component public class LogAspect { public void around(ProceedingJoinPoint joinpoint) { try { //前置通知 System.out.println(joinpoint.getTarget().getClass().getName()+" "+joinpoint.getSignature().getName()+"開始運行"); long start = System.currentTimeMillis(); // 執行被通知的方法 joinpoint.proceed(); // 后置通知 long end = System.currentTimeMillis(); System.out.println(joinpoint.getTarget().getClass().getName()+" "+joinpoint.getSignature().getName()+"方法運行了"+ (end - start) + " milliseconds."); } catch (Throwable t) { //例外通知 System.out.println(t.getMessage()); } finally { //最終通知 System.out.println("方法運行結束"); } } } ~~~ ~~~ @Service public class MyService { public void test1() { System.out.println("test1"); } public void test2() { System.out.println("test2"); } } ~~~ ~~~ <aop:config> <aop:aspect ref="logAspect"> <aop:pointcut expression="execution(* com.neuedu.model.service.*.*(..))" id="logpointcut"/> <aop:around method="around" pointcut-ref="logpointcut"/> </aop:aspect> </aop:config> ~~~ <aop:advisor> 顧問 Advisor表示只有一個通知和一個切入點的切面,由于Spring AOP都是基于AOP的攔截器模型的環繞通知的,所以引入Advisor來支持各種通知類型(如前置通知等5種),Advisor概念來自于Spring1.2對AOP的支持 ~~~ @Component public class MyAdvice implements MethodInterceptor{ @Override public void around(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("hahaha before advice"); } } ~~~ AOP配置 ~~~ <aop:config> <aop:pointcut id="performance2" expression="execution(* com.neuedu.model.aop.*.*(..))" /> <aop:advisor advice-ref="myAdvice" pointcut-ref="performance2"/> </aop:config> ~~~ 以上配置可以進一步簡化為: ~~~ <aop:config> <aop:advisor advice-ref="myAdvice" pointcut="execution(* com.neuedu.model.aop.*.*(..))"/> </aop:config> ~~~ 5種通知實現的接口類型: MethodBeforeAdvice(前置) AfterReturningAdvice(后置) MethodInterceptor(環繞) ThrowsAdvice(例外) AfterAdvice(最終) 除了在進行事務控制的情況下,其他情況一般不推薦使用該方式,該方式屬于侵入式設計,必須實現通知API
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看