[TOC] iN the Spring framework learning I mainly talk about some of the overview of Spring, Spring factory, Spring property injection and IOC introduction, among which the most important is IOC, the last chapter in IOC about the summary:
In addition to IOC, AOP is another important core in Spring: AOP. In Spring, both IOC and AOP must be able to develop XML and annotation development
1. Overview of AOP
From the professional point of view (do not ask me how professional, Baidu is my watch pot is wrong is sister-in-law) :
In the software industry, AOP for the abbreviation of Aspect Oriented Programming, meaning: section-oriented Programming, through pre-compilation and runtime dynamic proxy to achieve unified maintenance of program functions of a technology. AOP is a continuation of OOP, a hot topic in software development, and an important content in Spring framework. It is a derivative paradigm of functional programming. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development.
IOC and AOP concepts in Spring
The goal of section-oriented programming is to separate concerns. What is a focus? It’s what you do. It’s focus. If you are a son elder brother, do not have what life goal, everyday be clothes and clothes to hand in hand, eat and drink, all day only know to play a thing! So, every day when you wake up, you just want to eat and play (something you have to do), but before you can play, you need to get dressed, put on your shoes, make your bed, cook dinner, etc., etc., these are your focus, but you just want to eat and play, so what do you do? All these things are delegated to others. Before you go to the table, there is A dedicated servant A dress for you, the servant B wear shoes for you, the servant C help you fold the quilt, servant C to help you cook A meal, then you begin to eat, to play (this is your day business), after you finish your business, come back, and then A series of servants began to help you do this do that, then the day is over! The advantage of AOP is that you only need to do your job and others will do the rest for you. Maybe one day, you want to run naked, don’t want to wear clothes, then you just fire servant A! Perhaps, some day, you will want to take some money with you before you go out, so you can hire another servant to take it out for you! This is AOP. Each person to perform their own duties, flexible combination, to achieve a configurable, pluggable program structure. From a Spring perspective, the greatest use of AOP is the ability to provide transaction management. Transaction management is a concern, your business is to access the database, and you don’t want to deal with transactions (too annoying), so Spring automatically starts transactions for you before you access the database, and automatically commits/rolls back transactions for you after you have accessed the database!
1, 1 why to learn AOP
The origin of Spring AOP :AOP was first proposed by the ORGANIZATION of the AOP Federation, which developed a set of specifications. Spring introduces AOP ideas into the framework and must comply with the AOP consortium’s specifications.
Aop addresses some real-world development issues:
- AOP solves some of the problems encountered in OOP. OOP is a continuation and extension of OOP.
Enhancements to the program: Without modifying the source code:
- AOP can perform permissions verification, logging, performance monitoring, and transaction control.
1, 2 AOP low-level implementation: proxy mechanism (understanding)
The underlying AOP of Spring uses two proxy mechanisms:
- JDK dynamic proxies: Generate proxies for classes that implement interfaces.
- Dynamic proxies for Cglib: Proxies are generated for classes that do not implement interfaces. Underlying bytecode enhancement techniques are applied to generate subclass objects of the current class
Spring implements automatic proxy, classes that implement the interface use JDK dynamic proxy by default, on the contrary, classes that do not implement the interface use Cglib dynamic proxy by default. Those who are interested can know about it.
JDK dynamic proxies enhance methods in a class:
public class MyJDKProxy implements InvocationHandler {
private UserDao userDao;
public MyJDKProxy(UserDao userDao) {
this.userDao = userDao;
}
// Write tool method: generate proxy:
public UserDao createProxy() {
UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao
.getClass().getClassLoader(), userDao.getClass()
.getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("Permission verification ================");
}
returnmethod.invoke(userDao, args); }}Copy the code
Cglib dynamic proxy enhances methods in a class:
public class MyCglibProxy implements MethodInterceptor {
private CustomerDao customerDao;
public MyCglibProxy(CustomerDao customerDao) {
this.customerDao = customerDao;
}
// Generate proxy method:
public CustomerDao createProxy() {
// Create a Cglib core class:
Enhancer enhancer = new Enhancer();
// Set the parent class:
enhancer.setSuperclass(CustomerDao.class);
// Set the callback:
enhancer.setCallback(this);
// Generate proxy:
CustomerDao customerDaoProxy = (CustomerDao) enhancer.create();
return customerDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
if ("delete".equals(method.getName())) {
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("Logging ================");
return obj;
}
returnmethodProxy.invokeSuper(proxy, args); }}Copy the code
2, Spring based on AspectJ for AOP development introduction (XML way) :
First, the reason why Spring doesn’t just do Spring AOP development directly, instead of Aspectj, is because Spring’s own implementation of AOP development (traditional AOP development) is so cumbersome and inefficient that traditional AOP development has been largely abandoned. Conversely, Aspectj’s AOP development is more efficient, so AOP development is generally Spring’s ASPectJ-based AOP development.
2.1 Terminology in AOP development:
Aop is a very advanced concept, and of course there is a very technical term for it (how convoluted is that?).
Summarize the definition from a professional perspective (which is relatively dry and difficult to understand) :
Joinpoint: Joinpoints are the points that are intercepted. In Spring, these points refer to methods, because Spring only supports join points of method types. Pointcut: Pointcuts are definitions of which JoinPoints we want to intercept. Advice: Advice means that all you need to do after intercepting Joinpoint is advise. There are pre-notification, post-notification, exception notification, final notification, and surround notification. Introduction: Introduction is a special kind of notification. Introduction dynamically adds methods or field. Target: The broker’s Target Weaving: The process of applying enhancements to Target objects to create new proxy objects spring uses dynamic proxy Weaving. AspectJ, on the other hand, uses compile-time weaving and class-in-time weaving proxies: when a class is enhanced by AOP weaving, the resulting Proxy class Aspect is a combination of pointcuts and introductions
Case analysis based on professional perspective (relatively easy to understand, what? Image quality is poor? Ahem… 1080p Blu-ray… Ah ah ah.. The eldest brother.. Don’t play… Don’t play… Don’t hit your face) :
2.2 Importing jar packages
Introducing JAR packages: basic six JAR packages, AOP alliance JAR package, Spring AOPjar package, aspectJ JAR package, Spring integration aspectJ JAR package
-
The development of the traditional spring AOP package: spring AOP — 4.2.4. The jar com.springsource.org.aopalliance-1.0.0.jar
-
AspectJ development kit: com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring – aspects – 4.2.4. The jar
2.3 Importing the Spring configuration file
Introducing AOP constraints:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
Copy the code
2.4 Write the target class
Create interfaces and classes:
public interface OrderDao {
public void save();
public void update();
public void delete(a); publicvoid find();
}
public class OrderDaoImpl implements OrderDao {
@Override
public void save() {
System.out.println("Save order...");
}
@Override
public void update() {
System.out.println("Modify order...");
}
@Override
public void delete() {
System.out.println("Delete order...");
}
@Override
public void find() {
System.out.println("Order inquiry..."); }}Copy the code
2.5 XML configuration of the target class
<! -- Target class configuration: enhanced class --><bean id="orderDao" class="com.gx.spring.demo3.OrderDaoImpl"></bean>
Copy the code
2.6 Integrate Junit unit tests
Premise: After introducing the jar package of spring-test.jar test and integrating Junit unit test, there is no need to register factories repeatedly each time, just write two annotations on the test class in a fixed format, inject the required properties directly, and then only care about your own test class
// Fixed annotation notation (prerequisite: introducing the jar package of spring-test.jar test)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {
@Resource(name = "orderDao") // Direct injection of the required properties (prerequisite: importing the jar package of spring-test.jar)
private OrderDao orderDao;
@Test
public voiddemo1() { orderDao.save(); orderDao.update(); orderDao.delete(); orderDao.find(); }}Copy the code
The following results are displayed when demo is run:
2.7 Notification Type
Here, we need to need to know about notification types (the first three commonly used) :
Pre-notification: Execute before the target method executes.
The rear notice
Surrounding the notification
Exception throw notification
Final notice
Notification type XML configuration:
2.8 Pointcut Expressions
Execution (expression)
Expression: [method access modifier] The package name of the method return value. Class names. Method names (method parameters)
The pointcut expression is therefore the package name of the execution([method access modifier] method return value. Class name. Method name (method parameter)
The method access modifier in [] is optional
Examples of the types of pointcut expressions:
public * com.gx.spring.dao. * .*(..) com.gx.spring.dao.*.*(..) com.gx.spring.dao.UserDao+.*(..) com.gx.spring.dao.. *. * (..)Copy the code
2.9 Writing a Facet class
Ok, now that you know the notification types and pointcut expressions you can write a cut class and play with it QAQ
public class MyAspectXml {
// Pre-enhanced
public void before(){
System.out.println("Pre-enhanced ==========="); }}Copy the code
2.10 Enhanced Configuration is complete
<! -- Configure the section class --><bean id="myAspectXml" class="com.gx.spring.demo3.MyAspectXml"></bean><! --> <aop:config> <! - configuration Angle expressions: which classes which methods need to be enhanced - > < aop: pointcut expression = "execution (* com. Gx. Spring. Demo3. OrderDao. Save (..) )" id="pointcut1"/> <! <aop:aspect ="myAspectXml"> < AOP :before method="before" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config>Copy the code
例 句 : Don’t tell me I’m handsome, I know.
2.11 Other enhanced Configurations:
<! -- Configure the section class --><bean id="myAspectXml" class="com.gx.demo3.MyAspectXml"></bean><! --> <aop:config> <! < AOP :pointcut expression=" Execution (* com.gx.spring.demo3.* dao.save (..)) )" id="pointcut1"/> <aop:pointcut expression="execution(* com.gx.spring.demo3.*Dao.delete(..) )" id="pointcut2"/> <aop:pointcut expression="execution(* com.gx.spring.demo3.*Dao.update(..) )" id="pointcut3"/> <aop:pointcut expression="execution(* com.gx.spring.demo3.*Dao.find(..) )" id="pointcut4"/> <! < AOP :aspect ref="myAspectXml"> < AOP :before method="before" pointcut-ref="pointcut1"/> < AOP :after-returning method="afterReturing"pointcut-ref="pointcut2"/> <aop:around method="around" pointcut-ref="pointcut3"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4"/> <aop:after method="after" pointcut-ref="pointcut4"/> </aop:aspect> </aop:config>Copy the code
3, Spring based on AspectJ for AOP development introduction (annotation method) :
3.1 Creating a Project and importing jar packages
The imported JAR packages are as follows:
3.2 Importing a Configuration file
3.3 Write the target class and configure it
Write the target class:
package com.gx.spring.demo1;
public class OrderDao {
public void save(){
System.out.println("Save order...");
}
public void update(){
System.out.println("Modify order...");
}
public String delete(){
System.out.println("Delete order...");
return "YanHan";
}
public void find(){
System.out.println("Order inquiry..."); }}Copy the code
The XML configuration:
<! -- Configure target class --><bean id="orderDao" class="com.gx.spring.demo1.OrderDao">
</bean>
Copy the code
3.4 Write the section class and configure it
Write the aspect class
package com.gx.spring.demo1;
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;
/** * section class: Section class for annotations * @author jt */
public class MyAspectAnno {
public void before(){
System.out.println("Pre-enhanced ==========="); }}Copy the code
The XML configuration:
<! -- Configure the section class --><bean id="myAspect" class="com.gx.spring.demo1.MyAspectAnno">
</bean>
Copy the code
3.5 Enhancements with annotated AOP object target classes
Open annotated AOP development in the configuration file
<! Turn on annotated AOP development in the configuration file --><aop:aspectj-autoproxy/>
Copy the code
The @aspect annotation on the class represents an Aspect class that injects properties into methods. The @before annotation represents a pre-enhancement
@Aspect
public class MyAspectAnno {
@Before(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
public void before(){
System.out.println("Pre-enhanced ==========="); }}Copy the code
3.6 Writing test classes
package com.gx.spring.demo1;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** * Spring AOP annotation development ** /
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {
@Resource(name="orderDao")
private static OrderDao orderDao;
public static void main(String[] args) { orderDao.save(); orderDao.update(); orderDao.delete(); orderDao.find(); }}Copy the code
Test results:
Spring’s annotation of AOP’s notification type
4.1@Before: pre-notification
@Aspect
public class MyAspectAnno {
@Before(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
public void before(){
System.out.println("Pre-enhanced ==========="); }}Copy the code
4.2@AfterReturning: post notification
A post-notification retrieves the method return value
// after notification:
@AfterReturning(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
public void afterReturning(Object result){
System.out.println("Rear enhancement ==========="+result);
}
Copy the code
Let’s borrow the XML diagram, the meaning is the same, the meaning is QnQ
4.3@Around: Circular notification
// Surround notification:
@Around(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("Surround front enhancement ==========");
Object obj = joinPoint.proceed();
System.out.println("Enhanced after surround ==========");
return obj;
}
Copy the code
4.4@AfterThrowing: exception throw notification
Make an exception QNQ before you test
// Exception throw notification:
@AfterThrowing(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )" throwing="e")
public void afterThrowing(Throwable e){
System.out.println("Exception throw enhancement ========="+e.getMessage());
}
Copy the code
4.5@After: Final notification
// Final notification
@After(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
public void after(){
System.out.println("Final enhancement ============");
}
Copy the code
Configuration of AOP pointcuts annotated by Spring
First of all, we found that in the process of Spring’s introduction to AOP development based on AspectJ, if there are too many methods, too many notifications, and too many functions on a method, the corresponding source code needs to be changed as soon as the requirements change. For better maintenance, so we have the configuration of AOP pointcuts. AOP pointcuts are configured to solve the problem nicely! Just manage the configuration of AOP pointcuts!
The specific code is as follows:
package com.gx.spring.demo1;
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;
/** * section class: Section class for annotations * @author jt */
@Aspect
public class MyAspectAnno {
// Pre-notification:
@Before(value="MyAspectAnno.pointcut2()")
public void before(){
System.out.println("Pre-enhanced ===========");
}
// after notification:
@AfterReturning(value="MyAspectAnno.pointcut4()",returning="result")
public void afterReturning(Object result){
System.out.println("Rear enhancement ==========="+result);
}
// Surround notification:
@Around(value="MyAspectAnno.pointcut3()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("Surround front enhancement ==========");
Object obj = joinPoint.proceed();
System.out.println("Enhanced after surround ==========");
return obj;
}
// Exception throw notification:
@AfterThrowing(value="MyAspectAnno.pointcut1()",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("Exception throw enhancement ========="+e.getMessage());
}
// Final notification
@After(value="MyAspectAnno.pointcut1()")
public void after(){
System.out.println("Final enhancement ============");
}
// Pointcut comments:
@Pointcut(value="execution(* com.gx.spring.demo1.OrderDao.find(..) )")
private void pointcut1(){}
@Pointcut(value="execution(* com.gx.spring.demo1.OrderDao.save(..) )")
private void pointcut2(){}
@Pointcut(value="execution(* com.gx.spring.demo1.OrderDao.update(..) )")
private void pointcut3(){}
@Pointcut(value="execution(* com.gx.spring.demo1.OrderDao.delete(..) )")
private void pointcut4(){}
}
Copy the code
If this article helped you at all, please give it a thumbs up. Thanks
Finally, if there is insufficient or improper place, welcome to criticize, grateful! If you have any questions welcome to leave a message, absolutely the first time reply!
Welcome everyone to pay attention to my public number, discuss technology together, yearning for technology, the pursuit of technology, good come is a friend oh…