Spring
Full stack open source framework
I. Problems solved
1. The IOC decouple
Through Spring’s IOC container, dependencies between objects are handed over to Spring to avoid hard-coded program coupling.
2. Simplify AOP programming
Spring’s AOP capabilities make it easier to do section-oriented programming.
3. Declarative Transaction @transaction
Transaction control can be done through annotations.
4. Integrate various frameworks and APIS to reduce the difficulty of use
Frameworks: Struts, Hibernate, MyBatis, Hessian, Quartz
API : JDBCTemplate、 JavaMail、RestTemplate
Second, core ideas
IOC Inversion of Control
Delegating the creation and management of Java objects to third parties (Spring Framework)
Purpose: To uncouple
How it works: Call the no-argument constructor through reflection to instantiate an object and store it in a container. No no-argument construct will fail to instantiate
2. DI Dependancy Injection 3
Assigns a managed Java object to a property
Purpose: To uncouple
Principle: Use reflection technology to set target object properties
AOP Aspect oriented Programming
A horizontal extraction technique that runs specific logic before and after specific methods
Purpose: To reduce duplicate code
Application scenarios: transaction control, permission verification, log recording, and performance monitoring
Special classes
-
BeanFactory – Top level interface for container classes – base specification
-
ApplictaionContext – Advanced interface for container classes – Internationalization, Resource Access (XML, configuration classes)
-
ClassPathXmlApplicationContext – project root directory path loading configuration document
-
FileSystemXmlApplicationContext – hard drive path under loading configuration document
-
AnnotationConfigApplicationContext – from annotation configuration class loading configuration
-
-
-
FactoryBean – Custom complex Bean creation process
-
BeanFactoryPostProcessor – After BeanFactory is initialized, it is postprocessed
-
Beanpostprocessor-bean objects are instantiated, dependency injected, and post-processed at the Bean level
Four, annotations,
1. The IOC type
-
@Component(“Bean ID”) [class] – The default ID is lowercase, equivalent to three annotations
-
@Controller
-
@Service
-
@Repository
-
-
@scope (“Bean lifecycle “)
-
Singleton [default] – Same as container life cycle
-
Prototype – Each fetch is new
-
Request – An HTTP request within the same range
-
Session-same in session scope
-
The application scope of globalsession-portlet-based is the same
-
-
@postconstruct – call after initialization
-
@predeStory – Called before destruction
2. DI type
-
@autoweird – Inject by type
You can use it with @Qualifier(name=”Bean ID”) if the object corresponding to the type is not unique
-
@resource (name=”Bean ID”, type= class) – Inject by ID by default, or by type if ID cannot be found
3. Configure the type
- @ComponentScan – The package path to be scanned
- @configuration – Indicates that this class is a Configuration class
- @propertysource – Introduces external configuration documentation
- @import – Loads other configuration classes
- @value – Assigns a Value to the property from the configuration document
- @bean – Stores the object returned by the method into the IOC container. The object ID is the method name, which can also be specified manually
4. Type of AOP
- @pointcut – Configures pointcuts
- @before-Pre-notification
- @afterRETURNING – Post notification
- AfterThrowing – Exception notification
- @after – Final notice
- @around – Circular notification
Five, the AOP
1. The term
- Joinpoint Joinpoint: all methods
- PointCut: The specific method you want to influence
- Advice/enhancement: crosscutting logic
- Target Target: The object to be proxied
- Proxy: An enhanced class woven into AOP
- Weaving in: Applying Advice to Target to generate a Proxy
- Aspect Aspect: Pointcut + enhancement
Purpose: To lock what crosscutting logic is inserted where
@Component
@Aspect
public class LogUtil {
/** * Pointcut expression * [access modifier] return value package name. Package name Package name Class name Method name (parameter table) * * [.] used to denote any package. Used in packages to indicate the current package and its subpackages * * [..] * 【*】 Used in the parameter table, means at least one parameter */
@Pointcut("execution(* com.lagou.service.impl.*.*(..) )"
public void pointcut(a){}
@Before("pointcut()")
public void beforePrintLog(JoinPoint jp){
Object[] args = jp.getArgs();
System.out.println("Pre-notification: beforePrintLog, parameter is:" + Arrays.toString(args));
}
@AfterReturning(value = "pointcut()",returning = "rtValue")
public void afterReturningPrintLog(Object rtValue){
System.out.println("AfterReturningPrintLog, return value:+ rtValue);
}
@AfterThrowing(value = "pointcut()",throwing = "e")
public void afterThrowingPrintLog(Throwable e){
System.out.println("Exception notification: afterThrowingPrintLog, exception is:"+ e);
}
@After("pointcut()")
public void afterPrintLog(a){
System.out.println("Final notification: afterPrintLog");
}
/** * wrap around notification */
@Around("pointcut()")
public Object aroundPrintLog(ProceedingJoinPoint pjp){
// Define the return value
Object rtValue = null;
try{
// Pre-notification
System.out.println("Advance notice");
// 1. Obtain parameters
Object[] args = pjp.getArgs();
// 2. Run pointcut methods
rtValue = pjp.proceed(args);
// post notification
System.out.println("Post notification");
} catch (Throwable t){
// Exception notification
System.out.println("Exception notification");
t.printStackTrace();
}finally {
// Final notification
System.out.println("Final notice");
}
returnrtValue; }}Copy the code
Declarative Transaction @transaction
1. Four features
Atomicity: Operations either all occur or none
Consistency: Transitions from one consistent state to another
Isolation: Transactions cannot be disturbed by other transactions
Durability: Data changes are permanent
2. Isolation level
Dirty Read: Reads data that is not Committed in another transaction. – Read Committed Reads
Repeatable Read: reads data from another update transaction and has different data contents. – Repeatable Read Indicates Repeatable Read
Phantom read: data read to another transaction INSERT or DELETE with different amounts of data read – Serializable
3. Communication behavior
- REQUIRED [default] – If there are no transactions, create a new one, and if one already exists, join it
- SUPPORTS – SUPPORTS the current transaction. If there is no transaction currently, it runs in a non-transactional manner – lookup
- Mandatory-use the current transaction, and throw an exception if there is no transaction currently
- REQUIRES_NEW – Creates a new transaction and suspends the current transaction if one exists
- NOT_SUPPORTED – Runs the operation in a non-transactional manner and suspends the current transaction if one exists
- NEVER – Runs non-transactionally and throws an exception if a transaction currently exists
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
Copy the code
4. Failure scenario
- Apply to methods that are not public
- Method calls in the same class
- Exception is eaten by a try catch
- Propagation setting error
- The rollbackFor setting is incorrect
- The database engine does not support transactions
Principle 5.
○ Through JDK dynamic proxy and Cglib dynamic proxy implementation, database transactions are ultimately a Connection transaction
○ Connection is obtained from the Connection pool (C3P0, Druid). Preparedstatements can be generated. Preparedstatements can run SQL statements directly by running the execute() method
○ In JDK 1.8, JDK dynamic proxies have better performance than Cglib dynamic proxies, but the disadvantage is that the proxied classes using JDK dynamic proxies need to implement at least one interface
1. JDK dynamic proxy
The proxied class must implement at least one interface
public class JdkDynamicProxyTest implements InvocationHandler {
private Target target;
private JdkDynamicProxyTest(Target target) {
this.target = target;
}
public static Target newProxyInstance(Target target) {
return (Target) Proxy.newProxyInstance(JdkDynamicProxyTest.class.getClassLoader(),
newClass<? >[]{Target.class},new JdkDynamicProxyTest(target));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
returnmethod.invoke(target, args); }}Copy the code
2. Cglib dynamic proxy
This is done by bytecode subclass inheritance
public class CglibProxyTest implements MethodInterceptor {
private CglibProxyTest(a) {}public static <T extends Target> Target newProxyInstance(Class<T> targetInstanceClazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetInstanceClazz);
enhancer.setCallback(new CglibProxyTest());
return (Target) enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
returnproxy.invokeSuper(obj, args); }}Copy the code
test
Target targetImpl = new TargetImpl();
Target dynamicProxy = JdkDynamicProxyTest.newProxyInstance(targetImpl);
Target cglibProxy = CglibProxyTest.newProxyInstance(TargetImpl.class);
Copy the code
Spring Bean lifecycle
- The reflection call constructs the instantiation Bean without arguments
- Set property values using reflection
- If the Bean implements the BeanNameAware interface, the setBeanName() method is called to pass in the ID value of the current Bean
- If the Bean implements the BeanFactoryAware interface, the setBeanFactory() method is called to pass in a reference to the current factory instance
- If the Bean implements the ApplicationContextAware interface, the setApplictaionContext() method is called to pass in a reference to the current ApplicationContext instance
- If the Bean associated with BeanPostProcessor call postProcessBeforeInitialization () method, the Bean processing – Spring AOP in this implementation
- If the Bean implements the InitializingBean interface, the afterPropertiesSet() method is called
- If the init-method property is specified in the configuration document, the method specified by that property is called
- If the Bean associated with BeanPostProcessor call postProcessAfterInitialization () method, the Bean can be used in the application
- If the scope of the Bean is singleton, place the Bean in an IOC container; If the scope is Prototype, hand the Bean to the caller
- If the Bean implements the DisposableBean interface, the destory() method will be called when the Bean is destroyed – if the destory-method property is set in the configuration document, the method specified by this property will be called
Spring Bean loop dependencies
process
- SpringBean A is instantiated, putting itself into the three-level cache, and during the instantiation process, SpringBean B is found to be dependent
- SpringBean B is instantiated, putting itself into the three-level cache, and during the instantiation process, SpringBean A is found to be dependent
- SpringBean B goes to the level 3 cache to get SpringBean A, which is not yet formed
- Upgrade SpringBean A to level 2 cache and do some scaling
- SpringBean B puts itself into level 1 cache once it is created
- SpringBean A gets SpringBean B from the level 1 cache
Unable to process scenarios
- Singleton Bean constructor loop dependencies
- Multi-instance Bean loop dependencies