一、bean生命周期
- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
- Bean实例化后对将Bean的引入和值注入到Bean的属性中
- 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法
- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法
- Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
二、bean注入方式
- 通过注解@Autowired,按照byType注入
- 通过注解@Resource,默认按照byName注入,也支持byType注入
- 通过setter方法注入
public class TestAction { // 注入对象 private UserService userService; // 一定要写被注入对象的set方法 public void setUserService(UserService userService) { this.userService = userService; } } <!--配置bean, 配置后该类由spring管理--> <bean name="testAction " class="TestAction"> <!--依赖注入, 配置当前类中相应的属性--> <property name="userService" ref="userService" /> </bean> <bean name="userService" class="com.UserServiceImpl" />
- 通过构造器注入
public class TestAction { // 注入对象 private UserService userService; // 一定要写被注入对象的set方法 public void TestAction (UserService userService) { this.userService = userService; } } <bean name="testAction " class="TestAction"> <constructor-arg ref="userService"></constructor-arg> </bean> <bean name="userService" class="com.UserServiceImpl" />
- spring bean默认是单例,如果需要多例模式需要多加一个配置scope=“prototype”
<bean name="userService" class="com.UserServiceImpl" scope="prototype" />
三、spring AOP
-
AOP描述
aop面向切面编程,一些切面可能有集中的代码,但是这些代码跟业务代码写在一起,如日志事务等。使用AspectJ注解,Spring XML配置实现aop -
jdk动态代理,生成的代理类继承了Proxy,由于java是单继承,所以只能实现接口,通过接口实现。springaop如果目标对象实现了接口则默认使用jdk动态代理
public interface Subject { public String SayHello(String name); }
public class RealSubject implements Subject { public String SayHello(String name) { return "hello " + name; } }
public class InvocationHandlerImpl implements InvocationHandler { // 这个就是我们要代理的真实对象 private Object subject; // 构造方法, 给我们要代理的真实对象赋初值 public InvocationHandlerImpl(Object subject) { this.subject = subject; } /** * 该方法负责集中处理动态代理类上的所有方法调用。 * 调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行 * @param proxy 代理类实例 * @param method 被调用的方法对象 * @param args 调用参数 * @return * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO 在代理真实对象前可以添加操作 //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 Object returnValue = method.invoke(subject, args); // TODO 在代理真实对象后可以添加操作 return returnValue; } public static void main(String[] args) { // 代理的真实对象 Subject realSubject = new RealSubject(); InvocationHandler handler = new InvocationHandlerImpl(realSubject); ClassLoader loader = realSubject.getClass().getClassLoader(); Class[] interfaces = realSubject.getClass().getInterfaces(); Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler); String hello = subject.SayHello("jiankunking"); } }
-
cglib动态代理,jdk实现动态代理需要通过实现接口,springaop目标如果没有实现接口则默认使用cglib动态代理
public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz) { // 设置需要创建子类的类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //通过字节码技术动态创建子类实例 return enhancer.create(); } // 实现MethodInterceptor接口方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // TODO 在代理真实对象前可以添加操作 // 通过代理类调用父类中的方法 Object result = proxy.invokeSuper(obj, args); // TODO 在代理真实对象后可以添加操作 return result; } public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); // 通过生成子类的方式创建代理类 SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class); proxyImp.say(); } }
-
spring aop实现方式
public class MyAspectJ { public void myBefort(JoinPoint joinPoint) { System.out.println("前置通知"); } public void myAfterReturning(JoinPoint joinPoint, Object ret) { System.out.println("后置通知"); } public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知前......"); Object obj = joinPoint.proceed(); System.out.println("环绕通知后......"); return obj; } public void myThrowint(JoinPoint joinPoint, Throwable e) { System.out.println("异常通知"); } public void myAfter(JoinPoint joinPoint) { System.out.println("最终通知"); } } <!-- 创建被代理类 --> <bean id="person" class="PersonImple"></bean> <!-- 创建切面类 --> <bean id="advice" class="MyAspectJ"></bean> <aop:config> <!-- 将切面类 声明“切面”,从而获得通知(方法) --> <aop:aspect ref="advice"> <!-- 声明一个切入点,所有的通知都可以使用 --> <aop:pointcut expression="execution(* com.xiaostudy.PersonImple.*(..))" id="myPointcut"/> <!-- 前置通知--> <aop:before method="myBefort" pointcut-ref="myPointcut"/> <!-- 后置通知:returning表示:后置通知的第二个参数名,内容是方法的返回值 --> <aop:after-returning method="myAfterReturning" returning="ret" pointcut-ref="myPointcut"/> <!-- 环绕通知 --> <aop:around method="myAround" pointcut-ref="myPointcut"/> <!-- 异常通知:throwing表示:异常通知的第二个参数,内容是异常信息 --> <aop:after-throwing method="myThrowint" throwing="e" pointcut-ref="myPointcut"/> <!-- 最终通知 --> <aop:after method="myAfter" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config> </beans>
-
通知(Advice)
前置通知@Before: 在连接点之前执行
返回之后通知@AfterReturning: 在连接点正常结束之后执行
抛出异常后执行通知@AfterThrowing: 方法抛出异常退出的话被执行
后置通知@After: 无论连接点通过什么方式退出,都会执行
环绕通知@Around: 在目标方法执行前和执行后执行 -
连接点(Join point)是指能被拦截到的点,在spring中这些点指方法,spring只支持方法类型的连接点
-
切点(Pointcut)一个切面并不需要通知所有的连接点(在spring中即不需要通知所有方法),切点则表示需要对哪些连接点进行拦截
-
切面(Aspect)切面是通知和切点的结合
-
织入(Weaving)织入是把切面应用到目标对象并创建新的代理对象的过程。spring采用动态代理织入
-
两个AOP执行顺序,aop类似同心圆结构,先执行的后结束,order越小优先级越高
aop2 Around begin
aop2 doBefore
aop1 Around begin
aop1 doBefore
aop1 Around end
aop1 doAfter
aop1 doAfterReturning
aop2 Around end
aop2 doAfter
aop2 doAfterReturning
四、事务隔离级别
PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
五、springmvc请求流程
- 用户发送请求至前端控制器DispatcherServlet。
- 前端控制器DispatcherServlet接收请求后,调用处理器映射器HandlerMapping。
- 处理器映射器HandlerMapping根据请求的url找到处理该请求的处理器Handler(即Controller),将处理器Handler返回给前端控制器DispatcherServlet。
- 前端控制器DispatcherServlet通过处理器适配器HandlerAdapter调用处理器Handler。
- 执行处理器Handler(即Controller,也叫后端控制器或应用控制器)。
- 处理器Handler执行完成后,返回ModelAndView(ModelAndView:实体数据和视图)给处理器适配器HandlerAdapter。
- 处理器适配器HandlerAdapter将处理器Handler执行的结果ModelAndView返回给前端控制器DispatcherServlet。
- 前端控制器DispatcherServlet将ModelAndView传给视图解析器ViewReslover。
- 视图解析器ViewReslover解析后返回具体视图View。
- 前端控制器DispatcherServlet对视图View进行渲染(即将模型数据填充至视图中)。
- 前端控制器DispatcherServlet响应用户。
参考内容
- https://baijiahao.baidu.com/s?id=1666448276232778855
- https://www.cnblogs.com/weiqihome/p/8922937.html
- https://blog.csdn.net/a745233700/article/details/89307518
- https://www.cnblogs.com/vingLiu/p/12052096.html
- https://blog.csdn.net/jiankunking/article/details/52143504
- https://www.cnblogs.com/xiaostudy/p/9535857.html
- https://blog.csdn.net/qq_35232663/article/details/79617270