企业网站建设文章成都网站建设 招聘

当前位置: 首页 > news >正文

企业网站建设文章,成都网站建设 招聘,东营网红桥,python培训价格ApplicationContext refresh的流程 12个步骤 prepareRefresh 这一步创建和准备了Environment对象#xff0c;并赋值给了ApplicationContext的成员变量 要理解Environment对象的作用 obtainFreshBeanFactory ApplicationContext 里面有一个成员变量#xff0c;Beanfactory b…ApplicationContext refresh的流程 12个步骤 prepareRefresh 这一步创建和准备了Environment对象并赋值给了ApplicationContext的成员变量 要理解Environment对象的作用 obtainFreshBeanFactory ApplicationContext 里面有一个成员变量Beanfactory bean的来源有 xml配置文件配置类扫描 prepareBeanFactory postProcessBeanFactory 是一个空实现留给子类实现的 invokeBeanFactoryPostProcessors bean工厂后处理器 registerBeanPostProcessors 注册bean后处理器 对bean的创建过程中各种功能的增强 initMessageSource MessageSource实现国际化的 initApplicationEventMulticaster 应用事件广播器 onRefresh 空实现留给子类实现 registerListeners 事件监听器 finishBeanFactoryInitialization finishRefresh
spirng bean 生命周期 阶段一处理名称检查缓存 1.1 把别名解析成实际名称再进行后续处理1.2若要factoryBean本身需要使用名称获取1.3singletonobjects是一级缓存放单例成品对象1.4singletonFactories是三级缓存放单例工厂1.5earlySingletonObjects是二级缓存放单例工厂的成品可称为提前单例对象
2.阶段二检查父工厂 - 1.父子容器的bean名称可以重复 - 2.优先找子容器的bean找到了直接返回找不到继续到父容器找 3.阶段三检查DependsOn 4.阶段四按Scope 创建bean * 1.创建singleton * 2.创建prototype * 3.创建其他scope 阶段五创建bean 1.创建bean实例 Autowired,唯一带参构造默认构造2.依赖注入 Autowired valueResource,ByName ByType 精确指定3.初始化- Aware接口处理,PostConstruct,InitializingBean,initMethod4.登记可注销bean 类型转换 销毁bean
spring 事务失效的几种场景及原因 1.抛出检查异常导致事务不能正确回滚 spring默认情况下只对runtimeException和Error这两个异常及其子类会回滚。如果是检查异常是不会回滚的 解决方案 Transactional(rollbackFor Exception.class) 2.业务方法内自己try-cach 异常导致事务不能正确回滚 原因事务通知只有捉到了目标抛出的异常才能进行后续的回滚处理如果目标自己处理掉异常事务通知无法知悉 解决1异常原样抛出 解决2手动设置TransactionStatus.setRollbackOnly() 3.aop切面顺序导致事务不能正确回滚 原因事务切面优先级最低但如果自定义的切面优先级和他一样则还是自定义切面在内层这时若自定义切面没有正确抛出异常那外层的事务切面没有办法感知异常。 解法同情况2 4.Transactional 一定要放在public的方法上否则无效 原因spring为方法创建代理、添加事务通知、前提条件都是该方法是public的 5.父子容器导致的事务失效 原因子容器的扫描范围过大把未加事务配置的service扫描进来 解法1各扫描各的不要图简便 解法2不要用父子容器所有bean放在同一个容器 6.调用本类方法导致传播行为失效 原因本类方法调用不经过代理因此无法增强 解法1依赖注入自己代理来调用 解法2通过AopContext拿到代理对象来调用 解法3通过CTWLTW实现功能增强 Transactional没有保证原子行为 原因事务的原子性仅涵盖insert,update,delete,select…for update语句select方法并不阻塞 8.Transactional方法导致的synchronized失效 原因synchronized保证的是目标方法的原子性环绕目标方法的还有commit等操作他们并未处于sync块内 解法1synchronized 范围阔大至代理方法调用 解法2使用select…for update替换select SpringMVC 执行流程 初始化阶段 1.在Web容器第一次用到DispatcherServlet的时候会创建其对象并执行init方法 2.init方法会创建Spring Web容器并调用容器refresh方法 3.refresh过程中会创建并初始化SpringMVC中的重要组件例如MultipartResolverHandlerMappingHandlerAdapterHandleExceptionResolverViewResolver等 4.容器初始化后会将上一步初始化好的重要组件赋值给DispatcherServlet的成员变量留待后用 匹配阶段 1.用户发送的请求统一到达的前端控制器DispatcherServlet 2.DispatcherServlet遍历所有HandlerMapping找到与路径匹配的处理器对象 1.HandlerMapping有多个每个HandlerMapping会返回不同的处理器对象谁先匹配返回谁的处理器。其中能识别RequestMapping的优先级最高2.对应RequestMapping的处理器是HandlerMethod它包含了控制器对象和控制器方法信息3.其中路径与处理器的映射关系在HandlerMapping初始化时就会建立好 3.将HandlerMethod连同匹配到拦截器生成调佣链对象HandlerExecutionChain返回 4.遍历HandlerAdpter处理器适配器找到能处理HandlerMethod的适配器对象开始调用 执行阶段 1.执行拦截器preHandle 2.由HandlerAdapter适配器调用HandlerMethod处理器 1.调用前处理不同类型的参数2.调用后处理不同类型的返回值 3.第二步没有异常1.返回ModelAndView2.执行拦截器postHandle方法3.解析视图得到View对象进行视图渲染 4.第2步有异常进入HandlerExceptionResolver异常处理流程 5.最后都会执行拦截器的afterCompletion方法 6.如果控制器方法标注了ResponseBody注解则在第二步就会生成json结果并标记ModelAndView已处理这样就不会执行第3步的试图渲染 spring注解大全 1.事务 EnableTransactionManagement 启用声明式的事务 Transactional 2.核心 Order 多个bean控制执行顺序 3.切面 EnableAspectAutoProxy 启用Aop自动代理 以下这些不是spring的注解是第三方spring-aspects的注解 Aspect //标记该类为切面类 Before After 4.组件扫描和配置类的 Component Controller Service Repository ComponentScan Conditional 组件扫描时做条件判断 bean加载时做条件判断 Configuration Bean Import Lazy 标注在类上表示类是延迟实例化和初始化的 PropertySource 加载外部properties文件 5.缓存 EnableCaching CacheConfig CacheEvict CachePut Cacheable Caching 6.依赖注入 Autowired Qualifier 依赖注入时同一类型有多个bean可以用名字进行区分 Value 7.mapping Mapping RequestMapping 建立请求路径和控制器方法的映射关系 GetMapping PostMapping PutMapping DeleteMapping PatchMapping 8.rest RequestBody 请求体里面的json数据转换成java数据 ResponseBody将java数据转换成json数据放到响应体 ResponseStatus控制响应的状态 RestController 是一个组合注解 组合了 Controller 和 ResponseBody 9.统一处理 ControllerAdvice ExceptionHandler RestControllerAdvice 10.参数 RequestHeader 请求头的信息 CookieValue PathVariable 获取路径参数 RequestParam 获取请求参数 后的或者表单的 11.转换和格式化 DateTimerFormat NumberFormat InitBinder 12.validation bean的校验 Validated 13 scope ApplicationScope RequestScope SessionScope ModelAttribute RequestAttribute SessionAttribute SessionAttributes 14.ajax CrossOrigin 解决ajax的跨域问题 spring-boot注解 1.EnableConfigurationProperties 启用 2.ConfigurationProperties bean 值的初始化 3.Configuration 注意 配置类其实就相当于一个工厂。 bean注解的方法就是工厂方法 Bean,不支持方法重载如果有多个重载方法仅有一个能入选为工厂方法。参数越多权重越高 Beanpublic Bean1 bean1(){System.out.println(new bean2…..);return new Bean1();}Beanpublic Bean1 bean1(Value(\({java.class.version}) String a){System.out.println(a:a);return new Bean1();} Bean //这个参数有2个权重高public Bean1 bean1(Value(\){java.class.version}) String a,Value(\({JAVA_HOME}) String b){System.out.println(bena1 a:a b:b);return new Bean1();}注意点3Configuration 默认会为标注的类生成代理其目的是保证Bean 方法互相调用时仍然能保证其单例特性 4.注意点4Configuration中如果含有BeanFactory 后处理器则实例方法会导致MyConfig提前创建造成其依赖注入失败。 // 问题复现 public class TestConfiguration {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.registerBean(myConfig,Myconfig.class);context.refresh();System.out.println(context.getBean(Myconfig.class));System.out.println();}Configuration()static class Myconfig{Beanpublic Bean1 bean1(){System.out.println(bean1().....);return new Bean1();}Beanpublic Bean2 bean2(){System.out.println(bean2().....);return new Bean2();}Value(\){java.class.version})private String version;Bean // 这个实现了BeanFactory后处理器public MapperScannerConfigurer configurer(){MapperScannerConfigurer scanner new MapperScannerConfigurer();scanner.setBasePackage(aaa);return scanner;}Beanpublic Bean3 bean3(){System.out.println(Bean3():version); // 这个version无法获取了因为提前有后处理器在这个Configuration类里面所以这个Myconfig提前创建了所以他的功能没有增强。Value 这些增强没有了。return new Bean3();}class Bean3{}class Bean1{}class Bean2{}} } 解决办法 bean工厂后处理器在配置类中定义就用 static 修饰 如果想在Bean修饰的方法依赖注入用局部变量就可以,用参数注入尽量不要用成员变量来注入 Beanpublic Bean3 bean3(Value(${java.class.version}) String version){System.out.println(Bean3():version); // 这个version无法获取了因为提前有后处理器在这个Configuration类里面所以这个Myconfig提前创建了所以他的功能没有增强。Value 这些增强没有了。return new Bean3();}15.Import 放在 Configuration配置类上 import5种用法 public class TestImport {public static void main(String[] args) {// 普通容器GenericApplicationContext context new GenericApplicationContext();//后处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());//注册beancontext.registerBean(Myconfig.class);//refreshcontext.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}}Configuration // Import(bean1.class) // 1.引入单独bean // Import(OtherConfig.class) // 2.引入一个配置类 // Import(MySelector.class) // 3.通过MySelector实现了引入多个类 MySelector本身不会注册成bean // Import(MyRegister.class) // 4.通过MyRegister注册器引入多个类MyRegister本身不会注册成beanImport(MySelector2.class) // 5.通过MySelector2注册器实现了DeferredImportSelector引入多个类MySelector2本身不会注册成beanstatic class Myconfig{}static class MySelector2 implements DeferredImportSelector{Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{Bean3.class.getName(),Bean4.class.getName()};}}static class MyRegister implements ImportBeanDefinitionRegistrar {Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {registry.registerBeanDefinition(bean5, BeanDefinitionBuilder.genericBeanDefinition(Bean5.class).getBeanDefinition());}}static class MySelector implements ImportSelector{Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{Bean3.class.getName(),Bean4.class.getName()};}}Configurationstatic class OtherConfig{Beanpublic Bean2 bean2(){return new Bean2();}}static class bean1{}static class Bean2{}static class Bean3{}static class Bean4{}static class Bean5{} } 16.Import-DeferredImportSelector public class TestDeferredImport {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();DefaultListableBeanFactory beanFactory context.getDefaultListableBeanFactory();beanFactory.setAllowBeanDefinitionOverriding(false); // 不允许同名定义覆盖AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);context.registerBean(Myconfig.class);context.refresh();System.out.println(context.getBean(MyBean.class));}// 1.同一个配置类中Import 先解析 Bean 后解析// 2.同名定义默认后面解析的会覆盖前面解析的// 3.不允许覆盖的情况下如何能让Myconfig主配置类的配置优先虽然覆盖方式能解决// 4.Import 导入的类MyDeferredImportSelector 实现了DeferredImportSelector 最后工作可以简单认为先解析Bean再解析ImportConfigurationImport(MyDeferredImportSelector.class)static class Myconfig{ // 主配置 -程序员自己配置的Beanpublic MyBean myBean(){return new Bean1();}}static class MyDeferredImportSelector implements DeferredImportSelector{Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{OtherConfig.class.getName()};}}Configurationstatic class OtherConfig{ // 从属配置 - 自动配置BeanConditionalOnMissingBeanpublic MyBean myBean(){return new Bean2();}}interface MyBean{}static class Bean1 implements MyBean {}static class Bean2 implements MyBean {} } Springboot 自动配置 SpringbootApplication 是一个组合注解这个注解包含下面这些 SpringBootConfiguration 标记了这个类其实就是个配置类没什么特别的ComponentScan 用来在组件扫描时进行排除也会排除自动配置类EnableAutoConfiguration是一个组合注解 AutoConfigurationPackage -用来记住扫描的起始包Import(AutoConfigurationImportSelector.class)可以分离主从配置。用来加载META-INF/spring.factories中的自动配置类
Spring中有哪些设计模式 1.Spring中的Singleton Bean 是否是单例模式 spring中的singleton bean 并非实现了单例模式singleton bean 只能保证每个容器内想通的id的bean单例spirng中也有单例模式 2.Spring中的Builder 构建器模式 他的主要亮点有三处 1.较为灵活的构建产品对象 2.在不执行最后的build方法前产品对象都不可用 3.构建过程采用链式调佣看起来比较爽 spring中体现Builder模式的地方 org.springframework.beans.factory.support.BeanDefinitionBuilderorg.springframework.web.util.UriComponentsBuilderorg.springframework.http.ResponseEntity.HeadersBuilderorg.springframework.http.ResponseEntity.BodyBuilder 3.Spirng中的Factory Method 工厂方法模式 4.Spring 中的 Adapter 适配器模式 把一套接口转换成调用者所期望的接口 5.Spring 中的 Composite 组合器模式 6.spring 中的 Decorator 装饰器模式 对目标对象做功能增强避免子类继承进行功能可扩展 7.spring中的 Proxy 代理模式 对目标对象的控制和访问 8.Spring 中的 Chain of Responsibility 责任链模式 拦截器 9.Spirng 中的 Observer 观察者模式 ApplicationListener 监听器 ApplicationEventMulticaster 发送器 ApplicationEvent 事件对象 10.Spring 中的Strategy 策略模式 11.Spring 中 的 Template Method 模板方法 大部分以Template 命名的类 如jdbcTemplate TransactionTemplate很多以 Abstract命名的类如AbstractApplicationContext 创建代理要点 要完全理解循环依赖需要理解代理对象的创建时机掌握proxyFactory创建代理的过程理解AdvisorAdvicePonitcut 与 Aspect掌握AnnotationAwareAspectJAutoProxyCreator筛选Advisor合格者创建代理的过程 proxyFactory的基本使用 总结:Advisor 是最基本的切面Aspect 切面对应一个或多个Advisor切面最基本的Advice 是MethodInterceptor其他的Advice最终都将适配为MethodInterceptor创建代理的方式 实现了用户自定义接口采用jdk动态代理没有实现用户自定义接口采用cglib代理设置了setProxyTargetClasstrue同意采用cglib代理 切面、切点、通知等不会被代理AnnotationAwareAspectJAutoProxyCreator 调用时机创建阶段、依赖注入阶段、初始化阶段 // 编程方式 public class APP64_2 {public static void main(String[] args) {// aspect (通知)advice pointcut切点一个切面类可能有一个多个通知方法// advisor 更细粒度的切面包含一个通知和切点ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(new Target1()); // 设置目标对象// 添加通知MethodInterceptor 是环绕通知 // proxyFactory.addAdvice((MethodInterceptor) invocation - { // try { // System.out.println(befor…); // return invocation.proceed(); // 调用目标 // } finally { // System.out.println(atfer….); // } // });// 设置切点AspectJExpressionPointcut pointcut new AspectJExpressionPointcut();pointcut.setExpression(execution(* foo()));proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation - {try {System.out.println(before1…);return invocation.proceed(); // 调用目标} finally {System.out.println(after1…);}}));proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation - {try {System.out.println(before2…);return invocation.proceed(); // 调用目标} finally {System.out.println(after2…);}}));proxyFactory.addInterface(I1.class); // proxyFactory.setProxyTargetClass(true);I1 proxy (I1) proxyFactory.getProxy(); // 创建代理对象System.out.println(proxy.getClass());proxy.foo();proxy.bar();}interface I1{void foo();void bar();}static class Target1 implements I1{Overridepublic void foo() {System.out.println(target1 foo);}Overridepublic void bar() {System.out.println(target1 bar);}}} // 使用注解的方式 package org.springframework.aop.framework.autoproxy;public class APP64_1 {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean(aspect1,Aspect1.class);context.registerBean(aspect2,Aspect2.class);context.registerBean(aspect3,Aspect3.class);context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class); // 自动代理后处理器context.refresh();AnnotationAwareAspectJAutoProxyCreator creator context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);// 这里是演示一下 自动代理后处理器 是怎么创建代理对象的 // wrapIfNecessary 是protected 为了实验可以成功把这个当前这个类放在了同包下测试Object o creator.wrapIfNecessary(new Target1(), target1, target1);System.out.println(o.getClass()); // 是代理类Object b creator.wrapIfNecessary(new Aspect1(), aspect1, aspect1);System.out.println(b.getClass()); // Aspect1是aop的基础设施所有就不用代理对象}Aspectstatic class Aspect1{Around(execution(* com.libin..autoproxy..foo())) // 对应成一个Advisor切面public Object around(ProceedingJoinPoint pjp) throws Throwable {try {System.out.println(aspect1 around before);return pjp.proceed();} finally {System.out.println(after….);}}}Aspectstatic class Aspect2{ // 对应成两个Advisor切面Before(execution(* foo()))public void before() {System.out.println(aspect2 before);}After(execution(* foo()))public void after() {System.out.println(aspect2 after);}}Aspectstatic class Aspect3{Before(execution(* bar())) // 对应成一个Advisor切面public void around() {System.out.println(aspect3 before…);}}static class Target1 {public void foo() {System.out.println(target1 foo);}}static class Target2 {public void bar() {System.out.println(target1 bar);}}} set循环依赖 一级缓存限制bean 在BeanFactory中只存一份实现 Singleton scope 循环依赖图示只有一级缓存的情况下
二级缓存解决但是解决不了循环依赖里面有代理的情况 。 a先生成半成品代理对象后依赖注入但是b注入的时候是半成品的a不是成品的代理对象a 三级缓存
构造方法循环依赖 解决思路 第一种方式解决构造方法循环依赖 public class App60_1 {static class A{private static final Logger log LoggerFactory.getLogger(A);private B b;// 使用Lazy 让B后面再加载使用代理方式public A(Lazy B b){log.debug(A(B b){},b.getClass());this.b b;}PostConstructpublic void init(){log.debug(init());}}static class B{private static final Logger log LoggerFactory.getLogger(B);private A a;public B(A a) {log.debug(B({}),a);this.a a;}PostConstructpublic void init(){log.debug(init());}}public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(B.class));}} 第二种方式解决构造方法循环依赖 public class App60_1 {static class A{private static final Logger log LoggerFactory.getLogger(A);private ObjectFactoryB b; // 构造方法注入 ObjectFactory 工厂或者他的子类ObjectProperty可以延迟bean加载public A(ObjectFactoryB b){log.debug(A(B b){},b.getClass());this.b b;}PostConstructpublic void init(){log.debug(init());}}static class B{private static final Logger log LoggerFactory.getLogger(B);private A a;public B(A a) {log.debug(B({}),a);this.a a;}PostConstructpublic void init(){log.debug(init());}}public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(B.class));System.out.println(context.getBean(A.class).b.getObject());}} 第三种方式 public class App60_1 {static class A{private static final Logger log LoggerFactory.getLogger(A);private ProviderB b;// 注入 Provider 需要pom依赖//dependency// groupIdorg.aspectj/groupId// artifactIdaspectjweaver/artifactId// version1.9.19/version // /dependencypublic A(ProviderB b){log.debug(A(B b){},b.getClass());this.b b;}PostConstructpublic void init(){log.debug(init());}}static class B{private static final Logger log LoggerFactory.getLogger(B);private A a;public B(A a) {log.debug(B({}),a);this.a a;}PostConstructpublic void init(){log.debug(init());}}public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(A.class).b.get());System.out.println(context.getBean(B.class));}} 第四种方式用Scope方式不推荐就不看了了