SpringIOC/AOP
There are two unavoidable contents in each interview:
Pre knowledge: dynamic agent, static agent, singleton mode, factory mode and singleton lock
IOC: inversion of control
-
Description:
OOP is a design principle and the core of Spring framework
-
Reason for use:
A B two types attract each other to call B in A.
Traditional: A actively creates B
(1) new (A) produces B class objects and then calls B class method hard encoding coupling.
(2) a simple factory obtains B class objects, then calls the B class method, which is coupled with the factory.
IOC: IOC is to create B in advance and put it into the spring container.
The instance object of B is regarded as A Bean object, which is created and managed by the spring container. When we configure the sub elements in the configuration file, spring will automatically execute the setter method of B object in A (that is, A needs to have the setter method of B object). In this way, A does not obtain the instance object of B on its own initiative, Instead, it passively accepts the value set by spring. Then, this initiative becomes passive, which can be understood as "control reversal".
Through IOC, the coupling between them can be reduced. The application transfers the control of objects to the third-party container and manages these dependent objects through it, which completes the decoupling between the application and the dependent objects
-
Implementation method:
Dependency injection and dependency lookup.
Dependency injection: the application passively receives objects. The IoC container determines to inject different objects into different attributes through information such as type or name
Dependency injection mainly includes the following methods:
-
Set based method: public set() method that implements specific attributes to make IoC container call and inject objects of dependent types
-
Interface based: implement a specific interface for IoC container to inject objects of dependent types
-
Constructor based: a constructor that implements specific parameters. When creating an object, IoC container injects the object of the type it depends on
-
Annotation based: use Java's annotation mechanism to let IoC container inject objects of dependent types, such as @ Autowired. Com in Spring framework
Dependency search: it is a more active method than dependency injection. It will call the method provided by the framework to obtain the object when necessary. When obtaining, it needs to provide relevant configuration file path, key and other information to determine the state of the obtained object
- Common implementations:
- The first way
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- appoint class Property, created by construction method Bean example --> <bean id="person" class="com.mao.gouzao.Person"> </bean> </beans> public static void main( String[] args ) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println(ctx.getBean("person")); }
- The second way
definition
@Service public class UserServiceImpl { public void test(){ System.out.println(666); } }
obtain
@Autowired private static UserServiceImpl userService;
- The third way
definition
@Configuration public class MainConfig { @Bean public Person person(){ return new Person(); } }
Note: if the form of @ bean is used, the default name of the bean is the method name. If @ Bean(value = "bean name"), the bean name is specified
Go to the container to read the Bean information (pass in the configuration class)
obtain
public static void main( String[] args ) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class); System.out.println(ctx.getBean("person")); }
AOP
AOP -- asepct oriented programming
-
definition
The simple understanding of AOP is to encapsulate some reusable logic function blocks [unrelated to the main business process], which often occur in many parts of the main business process, but are basically similar everywhere, but are the logic or responsibility jointly called by the business modules, so as to reduce the repeated code of the system, reduce the coupling degree between modules, and facilitate the operability and maintainability in the future.
-
Usage scenario:
Commonly used in AOP are security verification [authentication], log operation, transaction operation, etc
-
Conceptual realization
The technologies to realize AOP are mainly divided into two categories: one is to use dynamic agent technology to decorate the message by intercepting the message to replace the execution of the original object behavior; The second is to use the way of static weaving and introduce specific syntax to create "aspects", so that the compiler can weave the code related to "aspects" during compilation.
-
AOP related terms
-
Advice
It is the function you want, that is, the above-mentioned security, transaction, log, etc. You define it first, and then use it where you want to use it.
-
Join point
This is a better explanation. There are many places where spring allows you to use notifications. Basically, the front and back of each method (both are OK), or when throwing an exception can be connection points. Spring only supports method connection points. Other aspects such as aspectJ can also allow you to use them in constructor or attribute injection, but that's not what we focus on. Just remember, Before and after (throwing exceptions) related to methods are connection points.
-
Pointcut
Define the pointcut based on the connection points mentioned above. If you have 15 methods in a class, there will be dozens of connection points. But you don't want to use notifications near all methods (use call weaving, and we'll talk about it later). You just want some of them to do something before, after or when throwing exceptions, Then use the tangent point to define these methods, let the tangent point to filter the connection points, and select the methods you want.
-
Aspect
Aspect is the combination of notification and entry point. Now I've found it. There's nothing about the connection point. The connection point is to make you understand the tangent point. Just understand this concept. The notification specifies what to do and when to do it (the time can be known through before,after, around, etc. in the method name), while the pointcut specifies where to do it (specify which method in the end). This is a complete aspect definition.
-
introduction
Allows us to add new method properties to an existing class. Isn't that the aspect (that is, the new method attribute: notification definition) used in the target class
-
target
The target class mentioned in the introduction, that is, the object to be notified, that is, the real business logic, can be woven into the aspect by us without our knowledge. And focus on the logic of the business itself.
-
Proxy
How to realize the whole set of AOP mechanism is through agents, that is, the implementation principle of AOP is based on dynamic agents.
-
Weaving
The process of applying facets to the target object to create a new proxy object.
-
-
Code implementation:
AOP application example 1 -- simulating AOP in the form of dynamic agent
(the following application examples are based on interface programming, so the author will not show the interface)
public class UserAImpl implements UserA{ @Override public void save() { System.out.println("Saving A Class users"); } @Override public void update() { System.out.println("Updating A Class users"); } }
public class UserBImpl implements UserB { @Override public void save() { System.out.println("Saving B Class users"); } @Override public void update() { System.out.println("Updating B Class users"); } }
AOP service enhancement (notification) class
public class DataValidateImpl implements DataValidate { @Override public void validate() { System.out.println("Data verification in progress"); System.out.println("Data verification completed!"); } @Override public void advice() { System.out.println("Operation successful"); } }
Agent factory
public class ProxyFactoryImpl implements ProxyFactory { //Create factory in singleton mode private static ProxyFactoryImpl proxyFactorySingleton; private ProxyFactoryImpl() {} public static ProxyFactoryImpl getProxyFactorySingleton() { if (proxyFactorySingleton == null) { proxyFactorySingleton = new ProxyFactoryImpl(); } return proxyFactorySingleton; } @Override public Object newProxyInstance(Object obj, InvocationHandler handler) { return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler); } }
Test class
public class AOPTest { public static void main(String[] args) { ProxyFactoryImpl proxyFactory = ProxyFactoryImpl.getProxyFactorySingleton(); //Operate class A user data UserA ua = (UserA) proxyFactory.newProxyInstance(new UserAImpl(), new UserAHandler(new UserAImpl(), new DataValidateImpl())); //What you get is a proxy object System.out.println(ua.getClass().getName()); ua.save(); ua.update(); System.out.println("********************"); //Operate class B user data UserB ub = (UserB) proxyFactory.newProxyInstance(new UserBImpl(), new UserBHandler(new UserBImpl(), new DataValidateImpl())); //What you get is a proxy object System.out.println(ub.getClass().getName()); ub.save(); ub.update(); //If you don't use a proxy to call, this is the result System.out.println("======================"); UserB ub2 = new UserBImpl(); ub2.save(); ub2.update(); } }
Operation results:
AOP application example - spring annotation uses AOP
User class
public class User { public void addUser(){ System.out.println("Added successfully!"); } }
Enhancement class
@Aspect public class MyUser { @Before(value = "execution(* com.xian.entity.User.*(..))") public void before() { System.out.println("before......"); } @After(value = "execution(* com.xian.entity.User.*(..))") public void after() { System.out.println("after......"); } }
configuration file
<bean id="user" class="com.xian.entity.User"></bean> <bean id="myUser" class="com.xian.entity.MyUser"></bean> <!-- Configuration file usage AOP --> <!-- <aop:config> Configure pointcuts <aop:pointcut expression="execution(* com.xian.entity.User.*(..))" id="userPC1"/> Configuration section Apply enhancements to methods <aop:aspect ref="myUser"> Configure enhanced types <aop:before method="before" pointcut-ref="userPC1"/> <aop:after method="after" pointcut-ref="userPC1"/> </aop:aspect> </aop:config> --> <!-- Use in annotation mode AOP --> <!-- open AOP agent --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy
Test class
public class UserTest { //private static Logger userLog = Logger.getLogger(User.class); @Test public void testUser(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User) context.getBean("user");//The user obtained through the bean container is actually just a proxy object User user2 = new User(); System.out.println(user == user2); MyUser mu = (MyUser) context.getBean("myUser"); //userLog.info("start calling User's Add method...); user.addUser();//Turn this into user2 to call add, and the enhanced logic function of the section will not be executed //userLog.info("normal end...); } }
Operation results:
Source of code implementation and screenshot: https://blog.csdn.net/h_xiao_x/article/details/72774496