What 1.Spring of aop that?
Comparison with OOP, the AOP is a process cross-cutting of some problems, these problems do not affect the cross-cutting of the main logic implementation, it will be scattered to various parts of the code, it is difficult to maintain. AOP is to separate these issues and the main business logic, business logic with the main purpose of decoupling.
2.aop application scenarios
Logging
ASD
Efficiency check
Transaction Management
3. Some of the concepts about aop
join point
-> connection point: The method of the target object
-> For example: dao four layer method to add the transaction, the four methods that become connection points.
Pointcut
-> tangent point: connection point set,
Cut-off point there are two key elements:
1.where: Where enhancement method?
2.when: When enhanced
The cut points can be understood as a table in the database, then the connection point is a data table.
Weaving
-> weaving: the proxy logic is added to the process on the target object is called weaving
advice
-> Notifications
It consists of two parts:
1. notification specific content (proxy logic code)
2.where: Where notification -> Agent logic code woven into that position audiences
Aspect
-> section
It is in a class AspectJ
In xml it is a label
target
-> the target object, the original object
aop Proxy
-> proxy object that contains the object code of the code and add the original object
AspectJ and the relationship 4.springAop
Relationship (1) aop with the springAop
aop is an idea, springAop achieve aop thought. ioc similar relationship with the di
(2) spring AOP provides two programming styles
@AspectJ support ------------> use aspectj comments
Schema-based AOP support -----------> xml aop: config namespace
Proof: spring, through source code analysis, we can know that spring bottom using JDK or CGLIB to complete the proxy and gives aspectj documents, and springAOP spring is different from the official website
(3) a brief summary
spring supports syntax of AspectJ, but the specific underlying implementation is to achieve its own spring.
JavaScript learn java syntax similar to the same.
5.springAop based AspectJ implementation
(1)
① use Java configuration enables @AspectJ support --- require catches aspectj appropriate pom file
@Configuration @ComponentScan("cn.cg.*")
//启动@AspectJ支持 @EnableAspectJAutoProxy public class AppConfig { }
② use xml configuration enables @AspectJ support
<aop:aspectj-autoproxy/>
(2) declare a Target
@Component public class IndexDao { public void query(){ System.out.println("query"); } }
(3) a declaration aspect
@Component @Aspect public class DaoAspect { }
(4) Sound point Mingqie
@Component @Aspect public class DaoAspect { // tangent point @Pointcut ( "Execution (cn.cg.target.IndexDao.query * (..))" ) public void PointCut () { // empty, if the execution code does not write } }
(5) declare a notification @Component the @Aspect
public class DaoAspect { @Pointcut ( "Execution (cn.cg.target.IndexDao.query * (..))" ) public void PointCut () {} // Keywords:
// When -> before -> front set notification -> specific logic code is woven into the front of the target method
@Before ( "PointCut ()" ) public void before () { // specific logic code System.out.println ( "before" ); } }
(6) Test
public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); IndexDao dao = (IndexDao) ac.getBean("indexDao"); dao.query(); } }
console:
before
query
success!!!
(7) Supported Pointcut Designators -> spring support entry point indicator
A total of nine kinds: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop-pointcuts
Introduce three of them -> general development of the most commonly used
①execution
For matching method execution join points ---> A method for performing matching connection point
For example: * public cn.cg.target.IndexDao.query (..)
Since the cut-off point is connected to a collection point, so support *, &&, || and other symbols
such as: * CN target.Index * * * (..)...
- the Execute given official expression syntax:
Execution (modifiers-pattern?-RET-pattern of the type Declaring-of the type-pattern? name-pattern (pattern-param)
throws-pattern?)
where the question mark indicates that the current entry may or may not, in which the semantics of the following
modifiers-pattern : visibility, such as public, protected process;
RET-pattern-type: the type of the return value, such as int, void, etc.;
Declaring-pattern-type: the method where the full path name of the class, such as com.spring.Aspect;
name-pattern: the type of method names, such as buisinessService ();
param-pattern: a method of parameter types, such as java.lang.String;
throws-pattern: the type of exception thrown methods, such as java.lang.Exception;
②within
Limits matching to join points within certain types -> limit matches the connection point of a specific type
(4) ||, && ,! use
Case ---> Presentation &&
UserDao for modification do control
@Component public class UserDao { public void Personquery(){ System.out.println("query"); } public void Personquery(String str){ System.out.println("query"+str); } }
Add cut-off point
// indexDao class for an incoming type String method parameter, and the parameter is present and only a
@Pointcut ( "WITHIN (cn.cg.target.IndexDao) && args (java.lang.String)" ) public void pointCut4 ( ) { } @Before ( "pointCut4 ()" ) public void before () { // specific logic code System.out.println ( "before" ); }
test:
public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); IndexDao dao = (IndexDao) ac.getBean("indexDao"); dao.query("index"); System.out.println("--------------------------"); UserDao dao2 = (UserDao) ac.getBean("userDao"); dao2.Personquery("person"); System.out.println("--------------------------"); dao.query(); System.out.println("--------------------------"); dao2.Personquery(); } }
console:
before
queryindex
--------------------------
queryperson
--------------------------
query
--------------------------
query
in conclusion:
IndexDao only enhances the query (String str) method
(5) target ----
time JDK proxy, and the proxy class interfaces Proxy point, point interfaces and when subclasses cglib agent (without using proxy)
/ ** * It should be noted here that, if the configuration settings proxyTargetClass = false, or the default is false, it is a JDK proxy, otherwise use a proxy CGLIB * JDK proxy implementation is based on the interface, the proxy class inherits Proxy , implement the interface. * The CGLIB inherit the proxy class to implement. Subsequent essays will be mentioned * so use target will ensure that target unchanged, association objects are not affected by this setting. * However, when using this object, according to the settings of the option to determine whether the object is found.
* / @Pointcut ( "target (com.chenss.dao.IndexDaoImpl)") // target object, which is the object being proxied. Limit the target object is com.chenss.dao.IndexDaoImpl class @Pointcut ( "the this (com.chenss.dao.IndexDaoImpl)") // current object, which is the proxy object, the proxy object when acquiring new target object through a proxy way objects, and the original value is not a @Pointcut ( "@ target (com.chenss.anno.Chenss)") // any method of the target object has @Chenss in @Pointcut ( "@ within (com.chenss.anno.Chenss ) ") // equivalent to @targ
Case:
Add cut-off point
@Pointcut("this(cn.cg.target.IndexDao)") public void pointCut5(){ } @Before("pointCut5()") public void before( ){ //具体的逻辑代码 System.out.println("before"); }
Creating interfaces
public interface Dao { public void query(); public void query(String str); }
IndexDao implement the interface
@Component public class IndexDao implements Dao { public void query(){ System.out.println("query"); } public void query(String str){ System.out.println("query"+str); } }
test:
public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); IndexDao dao = (IndexDao) ac.getBean("indexDao"); } }
console:
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy18 cannot be cast to cn.cg.target.IndexDao
at cn.cg.MainClass.main(MainClass.java:18)
why?
Already mentioned above because IndexDao realized Dao interfaces ---> object so as to obtain from the container -> proxy object, he extends Proxy implements Dao
So modify the test method
public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); Dao dao = (Dao) ac.getBean("indexDao"); dao.query(); } }
console:
query
Why not target method to enhance it?
Consistent with the cause of the problems described above, because the container is not obtained proxy object implementation class IndexDao
Solution: Use proxy cglib
@Configuration @ComponentScan("cn.cg.*")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig { }
console:
before
query
The reason: Because cglib agent is achieved through inheritance IndexDao