Java个人技术知识点总结(业务场景篇)

本文总结了Java开发中的关键知识点,包括Spring的IOC和AOP原理及其在业务场景中的应用。Spring的IOC简化了对象创建和依赖注入,AOP用于日志记录、事务处理等。文章还涉及了事务的ACID属性、权限控制、线程管理、缓存(如OSCache)以及Ajax的Session超时处理。同时,讨论了Java线程池、Servlet、Ant和Maven的使用场景,以及如何通过Lucene、BugFree、ExtJS和lucene进行全文检索和项目管理。
摘要由CSDN通过智能技术生成

业务场景篇

Spring的概述

     Spring是完全面向接口的设计,降低程序耦合性,主要是事务控制并创建bean实例对象。在ssh整合时,充当黏合剂的作用。IOC(Inversion of Control) 控制反转/依赖注入,又称DI(Dependency Injection) (依赖注入)  

IOC的作用:产生对象实例,所以它是基于工厂设计模式的

Spring IOC的注入

   通过属性进行注入,通过构造函数进行注入,

   注入对象数组注入List集合   

   注入Map集合      注入Properties类型

Spring IOC自动绑定模式:

        可以设置autowire按以下方式进行绑定

        按byType只要类型一致会自动寻找,            

        按byName自动按属性名称进行自动查找匹配.

AOP面向方面(切面)编程

AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面(切面)编程。

注:OOP(Object-Oriented Programming )面向对象编程

AOP主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。

Spring中实现AOP技术:

在Spring中可以通过代理模式来实现AOP

代理模式分为

静态代理:一个接口,分别有一个真实实现和一个代理实现。

动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。

动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有接口的支持,而cglib不需要,它是基于类的。

Spring AOP事务的描述:

在spring-common.xml里通过<aop:config>里面先设定一个表达式,设定对service里那些方法  如:对add* ,delete*,update*等开头的方法进行事务拦截。我们需要配置事务的传播(propagation="REQUIRED")特性,通常把增,删,改以外的操作需要配置成只读事务(read-only="true").只读事务可以提高性能。之后引入tx:advice,在tx:advice引用 transactionManager(事务管理),在事务管理里再引入sessionFactory,sessionFactory注入 dataSource,最后通过<aop:config> 引入txAdvice。

Spring实现ioc控制反转描述:

原来需要我们自己进行bean的创建以及注入,而现在交给spring容器去完成bean的创建以及注入。

所谓的“控制反转”就是 对象控制权的转移,从程序代码本身转移到了外部容器。

官方解释:

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。

事务概述

    在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。

事务的ACID属性

1.原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2.一致性(Consistency)

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)

3.隔离性(Isolation)

事务的隔离性是指一个事务的执行不能被其他事务干扰.

4.持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的.即使系统重启数据也不会丢失;在JDBC中,事务默认是自动提交的,每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚

为了让多个SQL语句作为一个事务执行:

(1)执行语句前调用 Connection 对象的 setAutoCommit(false);

以取消自动提交事务

(2)在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务

(3)在出现异常时,调用 rollback(); 方法回滚事务。

 

权限概述

          权限涉及到5张表:

用户表,角色表,权限表(菜单表),用户角色关联表,角色权限关联表

当用户登录时,根据用户名和密码到用户表验证信息是否合法,如果合法则获取用户信息,之后根据用户id再到用户角色关联表中得到相关连的角色id集合,之后根据角色id再到角色权限关联表中获取该角色所拥有的权限id集合,然后再根据权限id集合到权限表(菜单表)中获取具体的菜单,展现给当前登录用户,从而达到不同用用户看到不同的菜单权限。

我们通过ZTree来给角色赋权并且通过ZTree来展示菜单,以及通过ZTree来管 理菜单即增加和编辑菜单。

我们做的权限控制到url级别,为了防止用户不登录直接输入url访问的这个弊端,通过拦截器进行拦截验证。

 

OSCache业务场景

      在我以前的项目中,我们考虑了系统性能问题,这个时候我们采用了Oscache缓存,刚开始把这个功能交给了项目组中的另外一个同事来做的,但是他做完的时候他发现缓存中明明已经缓存了数据,但是在取得时候发现没有数据,我们项目经理让我去帮忙看看这个问题,我阅读完他的代码之后,我发现了他每次缓存的时候都是调用一个新的缓存对象的方法,结果出现了明明已经走了缓存的方法而取不到数据的问题,通过我多年的工作经验,我就想到了应该用单例模式去封装一个单例工具类来调用oscache。但是,在后来的测试过程中,发现当并发访问的时候也会出现上述的问题,这个时候我直接采取的DCL(双重判定锁)单例模式封装了工具类,既解决了线程安全问题,相对的性能问题也考虑到了,这个问题才得到了完善的解决。

 

线程概述

    线程的状态以及状态之间的相互转换:

    1、新建状态(New):新创建了一个线程对象。

  2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

  3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

  4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

  (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。

  (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。

  (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

  5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

实现线程的两种方式:

是继承Thread类或实现Runnable接口,但不管怎样,当new了这个对象后,线程就已经进入了初始状态

wait和sleep的区别:

线程访问:

锁池状态,之后等待锁释放,然后访问代码

wait

等待队列(释放资源)--->调用notify或者notifyall之后锁池状态--->( 等待锁释放)--->可运行状态--->运行状态---->访问代码

sleep,join

不释放资源-->结束后直接进入可运行状态--->运行状态---->访问代码

一个java控制台程序,默认运行两个线程,一个主线程,一个垃圾回收线程。

线程与进程的区别:

1.线程(Thread)与进程(Process)

进程定义的是应用程序与应用程序之间的边界,通常来说一个进程就代表一个与之对应     的应用程序。不同的进程之间不能共享代码和数据空间,而同一进程的不同线程可以共     享代码和数据空间。

2.一个进程可以包括若干个线程,同时创建多个线程来完成某项任务,便是多线程。

Ajax请求Session超时问题

     我在做项目时有时会遇到session超时问题,如果session超时,平常请求没有什么问题,通过拦截器可以正确跳到登陆页面,可是你如果用ajax请求的话这就出现问题了,因为ajax是异步的,局部刷新,所以登陆界面不会再全页面中显示,他只会显示到页面的一部分当中。所以根据我这几年的经验找到了我认为比较好的一种方法。因为那我用的框架是和struts2集成的,所以就在拦截器中进行设置:

首先判断session是否为空就是判断session是否超时,如果超时就取出请求的head头信息request.getHeader("x-requested-with"),如果不为空就和XMLHttpRequest(Ajax标识)进行比较 (request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest"))) 如果相等说明此请求是ajax请求。

如果是ajax请求就可以用response.setHeader("键","值")来设置一个标识来告诉用户这是ajax请求并且session超时时发出的,这样我就可以在回调函数中取出自己设置的那个唯一标识:XMLHttpRequest.getResponseHeader("");如果取出的值是和自己在后台中设置的值一样的话,就证明session已经超时,这样就可以设置window.location.replace("登陆界面"),来跳转到登陆界面了。

这样做虽然解决了问题,但是,会在每个回调函数中写入那些代码,这样的话代码就会显得特别零散,所以就想能不能定义一个全局的设置所以就找到了jqery的ajaxSetUp方法,通过ajaxSetUp对jqery的ajax进行全局的判断(ajaxSetUp就相当于ajax的拦截器),通过设置ajaxSetUp里的complete,它就相当于回调函数,这样那就弥补了上一方法的不足。

我做项目时还用到$(document).ajaxStart(),这是ajax请求时的事件;$(document).ajaxSuccess()&#

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值