jy-12-SPRINGMYBATIS02 - cloud notes 08 - Liu Cangsong

Keywords: Java Spring xml

Cloud notes

AOP aspect oriented programming

Section (child): cross section of a transaction

Features: insert (expand) cross section function for the software without changing the original function of the software

For horizontal functions, AOP can greatly simplify software development:

AOP not used:

After using AOP:

Develop an AOP case:

  1. Import Aspect J package

    Spring AOP bottom layer uses AspectJ implementation!

    <dependency>
    <groupId>aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.5.3</version>
    </dependency>
  2. Create slice component

    @Component
    @Aspect
    public class DemoAspect {
    //Declare that the test method will run before all the methods of userService
    @Before("bean(userService)")
    public void test(){
    System.out.println("Hello World!");
    }
    }
  3. Configuring Spring AOP: spring-aop.xml

    <!-- Configure component scanning -->
    <context:component-scan
    base-package="cn.tedu.note.aop"/>
    <!-- send @Aspect Note effective -->
    <aop:aspectj-autoproxy/>
  4. test

    Hello World! Will be in userService Execute before business method

notice

Target method: the business method intercepted by AOP is called target method

Slice method execution timing: just before and after the target method

  • @Before: the slice method executes before the target method

  • @After: the slice method executes after the target method

  • @After returning: the facet method is executed after the normal end of the target method

  • @AfterThrowing: the facet method executes after the target method exception

Case:

/**
* Creating a faceted component is an ordinary JavaBean
*/
@Component
@Aspect
public class DemoAspect {
//Declare that the test method will run before all the methods of userService
@Before("bean(userService)")
public void test(){
System.out.println("Hello World!");
}
@After("bean(userService)")
public void test2(){
System.out.println("After");
}
@AfterReturning("bean(userService)")
public void test3(){
System.out.println("AfterReturning");
}
@AfterThrowing("bean(userService)")
public void test4(){
System.out.println("AfterThrowing");
}
}

Around notification

Surround notification can be invoked before and after the business method.

Case:

@Component
@Aspect
public class Demo1Aspect {
/**
* Surround notification method:
* 1. Must have return value Object
* 2. Must have parameter ProceedingJoinPoint
* 3. An exception must be thrown
* 4. You need to call jp.proceed() in the method.
* 5. Returns the return value of the business method
* @param jp
* @return
* @throws Throwable
*/
@Around("bean(userService)")
public Object test5(ProceedingJoinPoint jp)
throws Throwable{
Object val = jp.proceed();
System.out.println("Business results:"+val);
throw new UserNotFoundException(
"Just don't let me log in");
}
}

breakthrough point

Used to locate the cut in position of APO: used to specify the cut in to the specific method class

  • bean component pointcuts

    • bean(userService)

    • bean(noteService)

    • bean(userService) || bean(noteService) || bean(notebookService)

    • bean(*Service)

  • Class pointcut

    • Within (class name)

    • Within (class name) | within (class name)

    • within(cn.tedu.note.service.impl.UserServiceImpl)

    • within(cn.tedu.note..impl.ServiceImpl)

  • Method pointcut (execution: execution)

    • Execution (modifier part of speech name. Method name (parameter type))

    • execution(* cn.tedu.note.service.UserService.login(..))

    • execution(* cn.tedu.note..Service.list*(..))

Note: consistent naming rules for classes and methods will help write effective pointcut expressions!

AOP underlying principle

Agent mode: do not change the original function to expand the new function for the software

AOP encapsulates the dynamic agent function and provides a simpler way to use it!

Classic interview questions:

AOP What is the underlying technology?
answer: Dynamic agent technology is used.

Key points:

  1. Spring AOP takes advantage of AspectJ AOP implementation!

  2. The underlying layer of AspectJ AOP uses dynamic proxies

  3. There are two kinds of dynamic agents

    • JDK dynamic proxy is automatically selected when the target method has an interface

    • Select CGLib dynamic proxy when the target method has no interface

The principle of AOP call can be analyzed by using exceptions:

java.lang.NullPointerException
at cn.tedu.note.service.impl.UserServiceImpl.login(UserServiceImpl.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy21.login(Unknown Source)
at cn.tedu.note.controller.UserController.login(UserController.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at cn.tedu.note.web.DemoFilter.doFilter(DemoFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

AOP interceptor filter

  1. Filter: intercept and process WEB requests!

  2. Spring MVC Interceptor: intercepts the request process of spring MVC

  3. AOP: intercept method requests between components in Spring

Declarative transaction

Programming transactions

Traditional programming transaction processing is very cumbersome:

try{
conn=open a connection
conn.setAutoCommit(false);
//Database operation 1
//Database operation 2
//Database operation 3
conn.commit();
}catch(e){
conn.rollback();
}finally{
conn.close()
}

Declarative transaction

The bottom layer of declarative transaction processing is realized by AOP, which can be used only by simple configuration

Use declarative transactions

  1. Configure transaction manager

<!-- spring-mybatis.xml -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"
ref="dataSource"/>
</bean>
<!-- Setting up annotation driven transaction management -->
<tx:annotation-driven
transaction-manager="txManager"/>

Just use transaction annotations on business methods

Case: batch deletion

  1. Develop persistence layer

    Persistent layer NoteDao

    int deleteNoteById(String noteId);

    SQL NoteMapper.xml

    <delete id="deleteNoteById"
    parameterType="string">
    delete from cn_note
    where cn_note_id=#{noteId}
    </delete>
  2. Business layer

    Business layer interface method NoteService

    int deleteNotes(String... noteIds)
    throws NoteNotFoundException;

    Implement the business method NoteServiceImpl

    @Transactional
    public int deleteNotes(String... noteIds)
    throws NoteNotFoundException {
    for(String id: noteIds){
    int n=noteDao.deleteNoteById(id);
    if(n!=1){
    throw new NoteNotFoundException("ID error");
    }
    }
    return noteIds.length;
    }

    When an exception NoteNotFoundException is thrown, the Spring transaction rollback operation will be triggered

  3. Test NoteServerTest

    @Test
    public void testDeleteNotes(){
    String id1 = "3febebb3-a1b7-45ac-83ba-50cdb41e5fc1";
    String id2 = "9187ffd3-4c1e-4768-9f2f-c600e835b823";
    String id3 = "ebd65da6-3f90-45f9-b045-782928a5e2c0";
    String id4 = "A";//"fed920a0-573c-46c8-ae4e-368397846efd";
    
    int n = service.deleteNotes(
    id1, id2, id3, id4);
    //int n = service.deleteNotes(
    // new String[]{id1, id2, id3, id4});
    System.out.println(n);
    }

    An exception occurs when the submitted ID is wrong, and the database transaction is rolled back

task

  1. Implement performance test function

  2. Add declarative transaction management to the business layer

Posted by DWilliams on Fri, 15 Oct 2021 14:19:01 -0700