Summary of AOP and jdbc in Spring

Keywords: Java JDBC Spring

catalogue

1, Foreword

2, Several concepts in AOP

3, Five types of notifications are implemented in three ways

1. Annotation implementation

2. Declaring a Pointcut simplifies the above code  

3. By configuration

4, Spring integrates jdbc

  1. Configure maven repository (pom.xml)

2. Add database profile

3. Introduction of database

4. Class to create database (student)

5. Add method

6. Delete function

7. Find function

8. Modify function

1, Foreword

Before talking about Spring's AOP, let's talk about whether our transaction should be completed in one layer. Should it be completed in Dao (data access layer) or service (business layer)?

Obviously, we should complete the transaction at the business level. For example, bank transfer is a transaction. It can be said that a transaction is completed only when one party completes the transfer and the other party completes the collection. If our transaction cannot be completed due to special circumstances, we must roll back and restore the original state, However, is it easy to cause redundancy to complete such public operations in the business layer as before? Therefore, Spring's AOP wants to peel off all common codes and place them separately in a class for centralized management. During the specific run time, these public codes are dynamically woven by the container.

From the official explanation: AOP (aspect oriented programming), it is a technology that can dynamically and uniformly add functions to the program without modifying the source code through precompile and runtime dynamic agent.

So let's use a dynamic proxy to implement how to split the public code

proxy class

import java.lang.reflect.Proxy;
import java.util.Arrays;

import org.junit.Test;

import com.DJX.Dao.UserDao;
import com.DJX.Dao.Impl.UserDaoImpl;

public class UserProxyTest {
	@Test
	public void testProxy() {
		UserDaoImpl userDaoImpl = new UserDaoImpl();
		Class[]clazz=userDaoImpl.getClass().getInterfaces();
		System.out.println(Arrays.toString(clazz));
		UserDao userdao = (UserDao) Proxy.newProxyInstance(UserProxyTest.class.getClassLoader(), clazz, new MyHandeler(userDaoImpl));
/*
Classes Gets the number of interfaces of the object
NewProxyInstance To create an agent, the three parameters are class loader, interface and implementation interface InvocationHandler
*/
		System.out.println(userdao.hashCode());
		userdao.add();
		int res =userdao.addUser("Zhang San");
		//Every time a method is called, the proxy's invoke will be called. addUser is the method, and "Zhang San" is args. At this time, myhandler is like a monitor to monitor the request proxy object at all times.
		System.out.println(res);
	}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

public class MyHandeler implements InvocationHandler{
 Object target;
 public MyHandeler(Object target) {
	// TODO Auto-generated constructor stub
	 this.target=target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	// TODO Auto-generated method stub
	System.out.println(method+"\t"+Arrays.toString(args));
	Object res = method.invoke(target, args);
	return res;
}
 
}

  Draw a picture to help understand

 

2, Several concepts in AOP

1. Connection point: those methods in the class can be enhanced. These methods are called connection points (@ pointcut is the connection point)

2. Pointcuts: the methods that are actually enhanced are called pointcuts

Such as execution(* com.DJX.Dao. *. * (..))

The * sign in the first part indicates any return value

The second part * sign com.DJX.Dao. * indicates any class under the com.DJX.Dao package

The * sign in the third part indicates any method under any class

The fourth part (..) represents the number of arbitrary parameters

3. Notification: the so-called notification refers to the code to be executed after intercepting the connection point. Notifications are divided into five categories: pre, post, exception, final and surround notifications

4. Aspect: action, the process of applying notification to the pointcut, which is implemented using the @ aspect class

3, Five types of notifications are implemented in three ways

1. Annotation implementation

First, set the xml file, scan the basic package, and set the  < AOP: AspectJ AutoProxy > otherwise, annotations will not have an effect

   <context:component-scan base-package="com.DJX"></context:component-scan>
      <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

The data link layer writing method is left to Spring for management

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
	public void add() {
		System.out.println("UserDao of add method");
	}
	public void save() {
		System.out.println("UserDao of save()method");
//		System.out.println(1/0);
	}
}

Proxy class required

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;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component//Basic class
@Aspect
public class UserProxy {
@Before(value="execution(* com.DJX.Dao.UserDao.save(..))")
//Annotation is executed before * indicates whether it is returned, com.DJX.Dao.UserDao package name, save method, (..) parameter
public void before() {
	System.out.println("Before method execution....");
}
@After(value="execution(* com.DJX.Dao.UserDao.save(..))")//Post notification
public void after() {
	System.out.println("After method execution....");
}
@AfterReturning(value="execution(* com.DJX.Dao.UserDao.save(..))")//Final notice
public void afterReturning() {
	System.out.println("Final notice");
}
@AfterThrowing(value="execution(* com.DJX.Dao.UserDao.save(..))")
public void afterthow() {
	System.out.println("Exception notification");
}
@Around(value="execution(* com.DJX.Dao.UserDao.save(..))")//Around Advice 
public void around(ProceedingJoinPoint p) {
	try {
		System.out.println("surround-Front");
		p.proceed();
	    System.out.println("surround-Post");
	} catch (Throwable e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

Effect display

2. Declaring a Pointcut simplifies the above code  

Modify the proxy class

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;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component//Basic class
@Aspect
public class UserProxy {
	@Pointcut(value="execution(* com.DJX.Dao.UserDao.save(..))")
public void point() {
	
}
//@Before(value="execution(* com.DJX.Dao.UserDao.save(..))")
	@Before(value="point()")
//Annotation is executed before * indicates whether it is returned, com.DJX.Dao.UserDao package name, save method, (..) parameter
public void before() {
	System.out.println("Before method execution....");
}
//@After(value="execution(* com.DJX.Dao.UserDao.save(..)") / / post notification
	@After(value="point()")//Post notification
public void after() {
	System.out.println("After method execution....");
}
//@AfterReturning(value="execution(* com.DJX.Dao.UserDao.save(..)") / / final notification
	@AfterReturning(value="point()")//Final notice
public void afterReturning() {
	System.out.println("Final notice");
}
@AfterThrowing(value="execution(* com.DJX.Dao.UserDao.save(..))")
public void afterthow() {
	System.out.println("Exception notification");
}
//@Around(value="execution(* com.DJX.Dao.UserDao.save(..)") / / surround notification
@Around(value="point()")//Around Advice 
public void around(ProceedingJoinPoint p) {
	try {
		System.out.println("surround-Front");
		p.proceed();
	    System.out.println("surround-Post");
	} catch (Throwable e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

3. By configuration

Configuration file xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
            <context:component-scan base-package="com.DJX"></context:component-scan>
           <bean id="proxy" class="com.DJX.Proxy.UserProxy2"></bean>
           <aop:config>
           <aop:pointcut expression="execution(* com.DJX.Dao.UserDao.save(..))" id="point"/>
           <aop:aspect ref="proxy">
               <aop:before method="before" pointcut-ref="point"/>
            <aop:around method="around" pointcut-ref="point"/>
              <aop:after method="after" pointcut-ref="point"/>
           </aop:aspect>
           </aop:config>
</beans>

Because of the configuration file, comments are not required

proxy class

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;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component//Basic class
@Aspect
public class UserProxy2 {

//Annotation is executed before * indicates whether it is returned, com.DJX.Dao.UserDao package name, save method, (..) parameter
public void before() {
	System.out.println("Before method execution....");
}

public void after() {
	System.out.println("After method execution....");
}

public void afterReturning() {
	System.out.println("Final notice");
}

public void afterthow() {
	System.out.println("Exception notification");
}

public void around(ProceedingJoinPoint p) {
	try {
		System.out.println("surround-Front");
		p.proceed();
	    System.out.println("surround-Post");
	} catch (Throwable e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

Effect display

4, Spring integrates jdbc

  1. Configure maven repository (pom.xml)

          <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
			<dependency>
			    <groupId>org.springframework</groupId>
			    <artifactId>spring-jdbc</artifactId>
			    <version>5.3.9</version>
			</dependency>
			<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
			<dependency>
			    <groupId>org.springframework</groupId>
			    <artifactId>spring-tx</artifactId>
			    <version>5.3.8</version>
			</dependency>

2. Add database profile

  3. Introduction of database

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
           <context:component-scan base-package="com.DJX"></context:component-scan><!-- scanning com.DJX File under package -->
           <context:property-placeholder location="classpath:druid.properties"/><!-- Load profile -->
           <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><!-- Create database pool -->
           <property name="driverClassName" value="${jdbc.driverClassName}"></property>
           <property name="url" value="${jdbc.url}"></property>
           <property name="username" value="${jdbc.name}"></property>
           <property name="password" value="${jdbc.password}"></property>
           </bean>
           <!-- Injection data source -->
           <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
           <property name="dataSource" ref="dataSource"></property>
           </bean>
</beans>

4. Class to create database (student)

import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

//@Data
@Getter
@Setter
@NoArgsConstructor
public class Student {
@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", password=" + password + "]";
	}
private Integer id;
private String name;
private String password;
public Student(String name,String password) {
	this.name=name;
	this.password=password;
}
}

5. Add method

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.DJX.bean.Student;
@Repository//Leave it to Spring to manage, so you need to scan and add the Repository
public class StudentDao {
	@Autowired//Automatic injection
	private JdbcTemplate jdbcTemplate;
	public int add(Student student) {
		
		return jdbcTemplate.update("insert into student (NAME,PASSWORD) VALUES(?,?)",student.getName(),student.getPassword());
	}
}

Test class

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.DJX.Dao.StudentDao;
import com.DJX.bean.Student;
//@BeforeClass, execute it before all methods, and after class, execute it after all methods are executed
//@before calls it once before each method is executed.
public class StudentTest {
	static StudentDao studentdao;
	@BeforeClass
	public static void init() {
		ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");//Parsing xml
		studentdao = context.getBean(StudentDao.class);
	}
	@Test
	public void test() {
		Student student = new Student("Wang Wu", "123456789");//create object
		ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");//Parsing xml
		StudentDao studentdao = context.getBean(StudentDao.class);
		studentdao.add(student);
		
	}
}

6. Delete function

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.DJX.bean.Student;
@Repository//Leave it to Spring to manage, so you need to scan and add the Repository
public class StudentDao {
@Autowired//Automatic injection
	private JdbcTemplate jdbcTemplate;
	public int delete(int id) {
		return jdbcTemplate.update("delete from student where id=?",id);
		
	}
}

Test class

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.DJX.Dao.StudentDao;
import com.DJX.bean.Student;
//@BeforeClass, execute it before all methods, and after class, execute it after all methods are executed
//@before calls it once before each method is executed.
public class StudentTest {
	static StudentDao studentdao;
	@BeforeClass
	public static void init() {
		ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");//Parsing xml
		studentdao = context.getBean(StudentDao.class);
	}
	@Test
	public void test() {
		int d=studentdao.delete(2);
		System.out.println(d>0?"Delete succeeded":"Deletion failed");
	
	}
}

7. Find function

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.DJX.bean.Student;
@Repository//Leave it to Spring to manage, so you need to scan and add the Repository
public class StudentDao {
	@Autowired//Automatic injection
	private JdbcTemplate jdbcTemplate;
	public List<Student> selectObject(){
		return jdbcTemplate.query("select * from student where name like ?", new BeanPropertyRowMapper<Student>(Student.class),"Lee%");
	}
}

Test class

import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.DJX.Dao.StudentDao;
import com.DJX.bean.Student;
//@BeforeClass, execute it before all methods, and after class, execute it after all methods are executed
//@before calls it once before each method is executed.
public class StudentTest {
	static StudentDao studentdao;
	@BeforeClass
	public static void init() {
		ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");//Parsing xml
		studentdao = context.getBean(StudentDao.class);
	}
	@Test
	public void test() {
		List<Student> list =studentdao.selectObject();
//		System.out.println(list);
		for(Student l:list) {
			System.out.println(l);
		}
		
	}
}

8. Modify function

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.DJX.bean.Student;
@Repository//Leave it to Spring to manage, so you need to scan and add the Repository
public class StudentDao {
	@Autowired//Automatic injection
	private JdbcTemplate jdbcTemplate;
	public int alters(String name,int id) {
		return jdbcTemplate.update("update student set name=? where id=?",name,id);
		
	}
}

Test class

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.DJX.Dao.StudentDao;
import com.DJX.bean.Student;
//@BeforeClass, execute it before all methods, and after class, execute it after all methods are executed
//@before calls it once before each method is executed.
public class StudentTest {
	static StudentDao studentdao;
	@BeforeClass
	public static void init() {
		ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");//Parsing xml
		studentdao = context.getBean(StudentDao.class);
	}
	@Test
	public void test() {
		int d=studentdao.alters("Debang", 3);
		System.out.println(d>0?"Modified successfully":"Modification failed");
	
	}
}

Posted by AQHost on Wed, 15 Sep 2021 18:08:33 -0700