框架类总结

来源:互联网 发布:甘地 印度独立 知乎 编辑:程序博客网 时间:2024/06/07 00:23

----------------------------------------------------------

sp,ring的工作原理

----------------------------------------------------------

ORM实现原理

-----------------------------------------------------------

Hibernate中的一级缓存和二级缓存

-------------------------------------------------------------

Red.is学习笔记

-----------------------------------------------------------------

redis常见面试题

-------------------------------------------------------------------

单点登录系统

-----------------------------------------------------------------

RDB与AOF比较

-------------------------------------------------------------------

JSP中一共预先定义了9个这样的对象,分别为:request、response、session、

application、out、pagecontext、config、page、exception

---------------------------------------------------

Http会话的四个过程:
建立连接,发送请求,返回响应,关闭连接。

----------------------------------------------------------------------------------

什么是restful

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。

资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数

Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673

资源操作:使用putdeletepostget,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。

一般使用时还是postgetPutDelete几乎不使用。


----------------------------------------------------------------------------------

Rest模式有四种操作,

    POST /uri 创建

    DELETE /uri/xxx 删除

    PUT /uri/xxx 更新或创建

    GET /uri/xxx 查看

-------------------------------------------------------------------------------------------------

Http和Https的区别,为什么Https是安全的

https是在http原本的协议上增加了层SSL协议,作用就是将明文的超文本传输协议变成加密的,

使得数据在服务端和客户端之间的传输是以密文的形式进行的——沃通(wosign)专业的数字证书CA机构

-----------------------------------------------------------------------

javaBean的作用:封装数据

---------------------------------------------------

MVC的优缺点

优点

1,。耦合性低

2.重用性高

3.可维护性高

4.有利于软件工程化管理。

缺点

   1.增加了系统结构和实现的复杂性

   2,。试图和控制器之间过于紧密连接,妨碍了他们的独立风格。

   3.试图对模型数据的访问效率低,试图可能需要多次调用才能获得足够的显示数据。

--------------------------------------------------------------------------------------------------

DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,

Service层主要负责业务模块的逻辑应用设计。

Controller层负责具体的业务模块流程的控制

----------------------------------------------------------------------------------------------------

servlet是单例吗,多线程下Servlet怎么保证数据安全的,Servlet的生命周期

何时创建:

    1.大部分情况下客户端首次请求对应servlet时创建.,filter的init是在tomcat启动时执行

     2.在web.xml中设置load-on-startup在启动服务器时创建

servlet是单例的,严格地说是一个ServletMapping对应一个单例实例(如果一个Servlet被映射了两个URL地址,会生成两个实例)

要维护Servlet线程安全有很多办法,通常是使用同步块(或方法)来保护共享数据,其次可以volatile、Lock一些锁机制,

还可以使用ThreadLocal来打通安全通道,另外还有原子操作也是用来保护数据安全,有非常多的选择。

生命周期:

     1.创建servlet实例

     2.调用init()方法初始化.

     3.servlet方法响应doXXX()方法

     4.调用servlet的destory方法.

---------------------------------------------------------------

doGet()和doPost()方法

当Http请求中的属性为get时,调用doGet()方法,当method属性为post时调用都Post()方法

get方法主要用来获取服务器的资源信息, 也可以向服务器传数据,但是一般推荐采用post方法来传数据

采用get方法传数据时,一般将数据添加到URL后面,并且二者用?连接,各个变量之间用&连接,而post方法传递数据是通过HTTP请求

的附件进行的,传送的数据量更大一点,一般默认为不受限制的。

由于get方法上传的数据添加在URL中,容易暴露,存在安全隐患,而post不存在

---------------------------------------------------------------------------------------------------------

MySQL存储引擎--MyISAM与InnoDB区别

MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,

但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。

------------------------------------------------------------------

   B+/-Tree原理及mysql的索引分析

      1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

       2.不可能在非叶子结点命中;

       3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

       4.更适合文件索引系统;

-----------------------------------------------------------------------------------

增加索引会增加磁盘占用
建立索引可以提升查询速度,即读速度;但在一定程度上降低写速度
数据库一般使用B*树作为索引
删除数据需要调整索引,所以会降低效率

----------------------------------------------------------

数据库索引类型:
根据数据库的功能,可以在数据库设计器中创建四种索引:唯一索引、非唯一索引、主键索引和聚集索引。

尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。

唯一索引:
唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。

数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。

非唯一索引:
非唯一索引是相对唯一索引,允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,数据库是允许将新创建的索引与表一起保存。

这时数据库不能防止添加将在表中创建重复键值的新数据。

主键索引:
数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,

主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

聚集索引(也叫聚簇索引):
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,

则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

  ---------------------------------------------------------------------------------------------------------------------

数据库的隔离

大多数的数据库系统的默认事务隔离级别都是:Read committed

而MySQL的默认事务隔离级别是:Repeatable Read


--------------------------------------------------------------------------------

mysql的悲观锁:

      其实理解起来非常简单,当数据被外界修改持保守态度,包括自身系统当前的其他事务,以及来自外部系统的事务处理,因此,在整个数据处理过程中,

将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制,但是也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,

即使在自身系统中实现了加锁机制,也无法保证外部系统不会修改数据。

      来点实际的,当我们使用悲观锁的时候我们首先必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,

当你执行一个更新操作后,MySQL会立刻将结果进行提交。

关闭命令为:set autocommit=0;

悲观锁可以使用select…for update实现,在执行的时候会锁定数据,虽然会锁定数据,但是不影响其他事务的普通查询使用。

此处说普通查询就是平时我们用的:select * from table 语句。在我们使用悲观锁的时候事务中的语句例如:

//开始事务

begin;/begin work;/start transaction; (三选一)

//查询信息

select * from order where id=1 for update;

//修改信息

update order set name='names';

//提交事务

commit;/commit work;(二选一)

此处的查询语句for update关键字,在事务中只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一条数据时会等待其它事务结束后才执行,

一般的SELECT查询则不受影响。

执行事务时关键字select…for update会锁定数据,防止其他事务更改数据。但是锁定数据也是有规则的。

查询条件与锁定范围:

1、具体的主键值为查询条件

比如查询条件为主键ID=1等等,如果此条数据存在,则锁定当前行数据,如果不存在,则不锁定。

2、不具体的主键值为查询条件

比如查询条件为主键ID>1等等,此时会锁定整张数据表。

3、查询条件中无主键

会锁定整张数据表。

4、如果查询条件中使用了索引为查询条件

明确指定索引并且查到,则锁定整条数据。如果找不到指定索引数据,则不加锁。

       悲观锁的确保了数据的安全性,在数据被操作的时候锁定数据不被访问,但是这样会带来很大的性能问题。因此悲观锁在实际开发中使用是相对比较少的。

mysql的乐观锁:

      相对悲观锁而言,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会对数据的冲突与否进行检测,如果发现冲突,

则让返回用户错误的信息,让用户决定如何去做。

      一般来说,实现乐观锁的方法是在数据表中增加一个version字段,每当数据更新的时候这个字段执行加1操作。这样当数据更改的时候,

另外一个事务访问此条数据进行更改的话就会操作失败,从而避免了并发操作错误。当然,还可以将version字段改为时间戳,不过原理都是一样的。

例如有表student,字段:

id,     name,      version
 
1         a              1

当事务一进行更新操作:update student set name='ygz' where id = #{id} and version = #{version};

此时操作完后数据会变为id = 1,name = ygz,version = 2,当另外一个事务二同样执行更新操作的时候,却发现version != 1,此时事务二就会操作失败,

从而保证了数据的正确性。

-----------------------------------------------------------------------------------------

CAS是乐观锁:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,

那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。

----------------------------------------------------------------------------------------------------------------------------------------------

Statement和PreparedStatement

1、相对比较安全,可以防止sql注入
2、有预编译功能,相同操作批量数据效率较高
PreparedStatement 是预编译 ,使用Statement时 sql 中要进行很多的单引号拼接字符串,首先是容易出错也比较麻烦,还有就是存在sql 注入问题这是从安全方面说的。 PreparedStatement  传参数时候用 了占位符 “?”很好的解决了以上Statement的问题。我所体会到得的就是这些。
PreparedStatement是在执行前先输入sql语句,Statement正好相反,是在执行的时候传入sql语句的。
这样的区别在于,PreparedStatement可以在传入sql后,执行语句前,给参数赋值,避免了因普通的拼接sql字符串语句所带来的安全问题,

而且准备sql和执行sql是在两个语句里面完成的,也提高了语句执行的效率。
Statement,就没有以前所说的功能了,我一般很少用

------------------------------------------------------------------------------------

JDBC连接MySQL
1.注册驱动
Class.forname("com.mysql.jdbc.Driver");
2.获取数据库连接
java.sql.Connection conn=java.sql.DriverManager.getConnection();
3.获取表达式
java.sql.Statement stmt=conn.createStatement("jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK","root","null");
4.执行SQL
java.sql.ResultSet rs=stmt.executeQuery("select * from XXX");
5.显示结果集里面的数据
while(rs.next()){
System.out.println(rs.get(i));
}
6.关流
rs.close();
stmt.close();
conn.close();

--------------------------------------------------------------------------------------------------------------

Hibernate 和 JDBC 的优缺点?

Hibernate:优:面向对象的思维,一些简单查询不需要sql语句。比较方便。使用者不必了解sql语句。
缺:面对一些复杂查询的时候不是很灵活,比如要查询多个表的数据作为结果集,用hibernate就要设置这些表的实体对象关联关系。

(虽然hibernate也可以执行sql,但是感觉效率不高)

jdbc:原生sql。需要了解sql语言。优:使用灵活
缺:jdbc需要大量的重复性劳动,比如单表查询,发出sql,根据结果集封装成对象。这种东西往往是类似的。 而hibernate只要一行代码就可以搞定。

---------------------------------------------------------------------------------------------------------------------

hibernate事务传播行为种类

------------------------------------------------------------------------------------------------------

跨域问题解决方案(HttpClient安全跨域 & jsonp跨域)

-------------------------------------------------------------------------------------

过滤器与拦截器的区别

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。

过滤器:所谓过滤器顾名思义是用来过滤的,在Java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,

然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),

或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话)。

filter 流程是线性的, url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter, servlet接收等.

监听器也叫Listener,是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。

(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)
2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预他,通过验证的少点,顺便干点别的东西)。

------------------------------------------------------------------------------------------

struts2工作流程

1.客户端浏览器发出HTTP请求.

2.根据web.xml配置,请求被filterdispatcher接受

3.根据web.xml配置,找到需要调用的action类和方法,并通过IOC方式,将值注入给action.

4.action调用业务逻辑组件处理业务逻辑

5.action执行完毕,根据struts.xml中配置找到对应的返回结果result,并跳转到相应页面.

6.返回http响应到客户端浏览器.

-------------------------------------------------------------------------

springmvc的几种controller

1.CommandController(命令控制器)

2 FormController(表单控制器)

3 WizardFormController(向导表单控制器)

----------------------------------------------------------------------------

SpringMVC运行原理

       1. 客户端请求提交到DispatcherServlet
        2.由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
        3.DispatcherServlet将请求提交到Controller
        4.Controller调用业务逻辑处理后,返回ModelAndView
       5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
        6.视图负责将结果显示到客户端

--------------------------------------------------------------------

SpringMVC的controller默认是单例的

------------------------------------------------------------------------------------

Spring MVC 比较 Struts2

1、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

2、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)

struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

3、 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,

将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl

-----------------------------------------------------------------------------------------------------

SpringMvc拦截器

--------------------------------------------------------------------------------------------------------

hibernate工作原理

1.读取并解析配置文件

2.读取并解析映射信息,创建SessionFactory

3.打开session

4.创建事务transaction

5.持久化操作

6.提交事务

7.关闭session

8.关闭sessionfactory

public class PersonTest {      private static SessionFactory sessionFactory;      static{          Configuration configuration = new Configuration();          //加载配置文件          configuration.configure();          //采用了工厂模式创建sessionFactory          sessionFactory = configuration.buildSessionFactory();      }         @Test      public void testSavePerson(){          Session session = sessionFactory.openSession();          Transaction transaction = session.beginTransaction();          Person person = new Person();          //由于在映射文件中已经说明主键的产生方式是hibernate内部产生,所以在程序中不用设置主键          person.setPname("reed");          person.setPsex("male");          session.save(person);          transaction.commit();          session.close();      }        }  
---------------------------------------------------------------------------------------------------------------------
hibernate三种状态:瞬时态(transient) 持久态(persistent) 游离态(detached)

语句转换状态

----------------------------------------------------------------------------------------------------------------

SessionFactory是线程安全的,可以被多个线程并发访问.

session是由sessionFactory创建的,在任务完成之后被关闭,是非线程安全的

(线程间不能共享session),它表示与数据库进行交互的一个工作单元。

--------------------------------------------------------------------------------------------------

mybatis两种占位符的区别

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,

那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
  
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 

如果传入的值是id,则解析成的sql为order by id.
  
3. #方式能够很大程度防止sql注入。
  
4.$方式无法防止Sql注入。

5.$方式一般用于传入数据库对象,例如传入表名.
  
6.一般能用#的就别用$.

------------------------------------------------------------------------------------------------

MyBatis 延迟加载,一级缓存,二级缓存设置

什么是延迟加载

        resultMap中的association和collection标签具有延迟加载的功能。

        延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息。使用关联信息时再去加载关联信息。


设置延迟加载

        需要在SqlMapConfig.xml文件中,在<settings>标签中设置下延迟加载。

        lazyLoadingEnabled、aggressiveLazyLoading

<!-- 开启延迟加载 -->
    <settings>
        <!-- lazyLoadingEnabled:延迟加载启动,默认是false -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- aggressiveLazyLoading:积极的懒加载,false的话按需加载,默认是true -->
        <setting name="aggressiveLazyLoading" value="false"/>
         
        <!-- 开启二级缓存,默认是false -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

Mybatis的一级缓存是指SqlSession。一级缓存的作用域是一个SqlSession。Mybatis默认开启一级缓存。

在同一个SqlSession中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。

当执行SQL时两次查询中间发生了增删改操作,则SqlSession的缓存清空。

 
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。

Mybatis需要手动设置启动二级缓存。在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;

第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则二级缓存清空。

----------------------------------------------------------------------------------------------------

mybatis工作原理

加载sqlmapconfig.xml创建sqlsessionfactory

sqlsessionfactory根据配置文件创建sqlsession

Executor(执行器),是一个接口(基本执行器、缓存执行器)
SqlSession内部通过执行器操作数据库

调用sqlsession.commit提交事务

调用sqlsession.close关闭会话

-----------------------------------------------------------------------------------------------------------------------

mybatis和hibernate的区别

mybatis是半自动的,hibernate是全自动的,就是说mybatis可以配置sql语句,对于sql调优来说是比较好的,hibernate会自动生成所有的sql语句,

调优不方便,hibernate用起来难度要大于mybatis

Hibernate应用场景: 试用需求,变化固定中小型项目

mybatis应用场景: 除了hibernate 的场景,主要应用需求项目较多的场景,  互联网项目; 敏捷开发。

----------------------------------------------------------------------------------------------------

session加载实体对象:首先去一级缓存,然后去二级缓存,然后才会发出sql语句去数据库查询(并存入相应的一级缓存,二级缓存并返回)

hibernate Session在加载实体对象的过程

--------------------------------------------------------------------------------------------------------------------

N+1问题是什么,应该怎样解决

N+1问题就是执行一次查询获取n条主数据后,由关联引起的执行n次查询从数据,它带来了性能的问题.

一般来说用过懒加载可以部分缓解N+1带来的性能问题.

-------------------------------------------------------------------------------------------------------

什么时候需要使用事务管理机制?

对数据库的数据进行批量或连表操作时,为了保证数据的一致性和正确性,我们需要添加事务管理机制进行管理。

当对数据库的数据进行操作失败时,事务管理可以很好保证所有的数据回滚到原来的数据,如果操作成功,则保证所有需要更新的数据持久化。

-------------------------------------------------------------------------------------------------------------------

事务,也是数据库事务,指的是作为单个逻辑工作单元执行的一系列操作。正常的情况下,操作应该顺利进行,与操作相关的所有数据库信息也成功地更新;

但是,如果在这一系列过程中任何一个环节出了差错,导致操作失败了,数据库中所有信息都必须保持操作前的状态不变。否则,数据库的信息将会一片混乱而不可预测。

一个逻辑工作单元要称为事务,必须满足ACID(原子性,一致性,隔离性和持久性)

A(Atomicity)原子性:数据库中事物执行的是原子操作,即不可再分,要么全部执行,要么全部不执行.

C(consistency)一致性: 只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

I(Isolation)隔离性 事务的执行是互不干扰的,一个事务不可能看到其他事务运行中的某一刻的状态.

D(Durability)持久性 意味着事务完成以后,该事务对数据库所做的更改便持久的保持在数据库中.

事务的结束只能有两种形式:提交和回滚。操作完全成功则提交,产生永久性的修改;操作不完全成功则回滚,恢复到事务开始前的状态。它们将结束一个事务。

(1)关闭自动提交事务。通过设置连接的自动提交事务属性为false,如下:
Connection conn = DriverManager.getConnection("连接URL","用户名", "密码");
//关闭自动提交事务
conn.setAutoCommit(false);

(2)如果执行顺利,提交事务;一旦发生异常,回滚(rollback)事务,如下:
try{
    conn.setAutoCommit(false);    //关闭自动提交事务
    stmt = conn.createStatement();   //创建会话
    stmt.executeUpdate("sql语句");
    conn.commit();     //提交事务
}catch(Exception e)
{
    e.printStackTrace();
    conn.rollback();   //回滚事务   
}

  

(3)关闭连接,如下:
finally{
    if(stmt !=null)
        stmt.close();
    if(conn !=null)
        conn.close();
}


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

项目中事务管理

手动编码方式(不常用)

申明式事务管理(ApplicationContext.XML文件配置的方式)

1.5.3.3配置事务管理器    <!-- 事务管理器 -->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="dataSource"/>    </bean>1.5.3.4配置事务的通知    <!-- 配置事务的增强 -->    <tx:advice id="txAdvice" transaction-manager="transactionManager">    <tx:attributes>  <!-- isolation="DEFAULT"隔离级别propagation="REQUIRED"传播行为read-only="false"只读timeout="-1"过期时间rollback-for=""-Exceptionno-rollback-for=""+Exception -->    <tx:method name="transfer" propagation="REQUIRED"/>    </tx:attributes>    </tx:advice>

申明式事务管理(注解的方式)

<aop:config>    <aop:pointcut expression="execution(* cn.itcast.transaction.demo2.AccountServiceImpl.transfer(..))" id="pointcut1"/>    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>    </aop:config>

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

开发中主要使用 Spring 的什么技术 ?
①. IOC 容器管理各层的组件
②. 使用 AOP 配置声明式事务
③. 整合其他框架.
----------------------------------------------------------------------------------------------------------

1.在默认情况下,spring创建bean是单例模式

2.如果在Spring配制文件时设置懒加载模式(lazy-init=”true”),在getBean时才会实例化对象。

3.如果scope=”prototype”时,则会变成多例,无论lazy-init的值是什么都只会在使用时才会创建,

<bean id="helloWorld"  class="reed1991.scope.HelloWorld" scope="prototype" lazy-init="false"></bean>

    当一个bean是多例模式的情况下,lazy-init为false或者default无效

----------------------------------------------------------------------------------------------------------

Spring 如何整合 Hibernate
整合 Hibernate, 即由 IOC 容器生成 SessionFactory 对象, 并使用Spring 的声明式事务
> 利用 LocalSessionFactoryBean 工厂 Bean, 声明一个使用 XML 映射文件的 SessionFactory 实例.

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">              <property name="configLocation">              <value>classpath:hibernate.cfg.xml</value>              </property>              </bean>  

> 利用 HibernateTransactionManager 配置 Hibernate 的事务管理器

<bean id="transactionmanager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">              <property name="sessionFactory">              <ref bean="sessionFactory"/>              </property>              </bean>  

-------------------------------------------------------------------------------------------------------------

Spring IOC   DI(控制反转,依赖注入)AOP(面向切面编程)

在Spring中,那些组成应用的主体及由Spring IOC容器所管理的对象被称之为Bean。
Spring的IOC容器通过反射的机制实例化Bean并建立Bean之间的依赖关系。
简单地讲,Bean就是由Spring IOC容器初始化、装配及被管理的对象。
获取Bean对象的过程,首先通过Resource加载配置文件并启动IOC容器,然后通过getBean方法获取bean对象,就可以调用他的方法。


spring依赖注入(DI)的三种方式

接口注入、构造器注入、Setter注入


Spring Bean的作用域:
Singleton:Spring IOC容器中只有一个共享的Bean实例,一般都是Singleton作用域。
Prototype:每一个请求,会产生一个新的Bean实例。
Request:每一次http请求会产生一个新的Bean实例。

Spring支持三种依赖注入方式,分别是属性(Setter方法)注入,构造注入和接口注入。

AOP(面向切面编程):将核心关注点和横切关注点分离开来.

        核心关注点:业务主要流程

        横切关注点:与业务关系不大.

AOP应用到项目中的好处,能够将与业务逻辑不相关的代码(如:日志、权限等)分离出来,减小相关业务类负担,

并能让一些通用需求(如:事务)得到更广泛的复用.

一些概念:

     1.切面:日志.安全性框架等,总之和业务逻辑没关系的就可以看做切面.

      2.通知:切面中的方法

      3.切入点:只有符合切入点才能把通知和目标方法结合在一起.

      4.连接点:客户端调用的方法

      5.织入:形成代理方法的过程.

AOP中各种通知

      前置通知: 在目标方法执行之前

      后置通知
                   *  在目标方法执行之后
                   *  可以根据returning获取目标方法的返回值

                          <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>

                           public void commit(JoinPoint joinPoint,Object val)

                    *  如果目标方法遇到异常,该通知不执行

     最终通知
                    *  在目标方法执行之后
                    *  无论目标方法是否遇到异常,都执行
                    *  经常做一些关闭资源

    异常通知
                    目的就是为了获取目标方法抛出的异常

    环绕通知
                     能控制目标方法的执行            

Spring AOP代理对象的生成     如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用cglibproxy

JDK动态代理和CGLIB字节码生成的区别?
 (1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
 (2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法

JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,它有几个要求
* 实现InvocationHandler
* 使用Proxy.newProxyInstance产生代理对象
* 被代理的对象必须要实现接口

使用JDK动态代理,目标类必须实现的某个接口,如果某个类没有实现接口则不能生成代理对象。
CGLib 必须依赖于CGLib的类库,Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,所以目标类和方法不能声明为final类型。

针对接口编程的环境下推荐使用JDK的代理。从执行效率上看,Cglib动态代理效率较高。

在hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的相关代理采用的是CGLib来执行。

加载配置文件,启动spring容器
 spring容器为bean创建对象
  解析aop的配置,会解析切入点表达式
  看纳入spring管理的那个类和切入点表达式匹配,如果匹配则会为该类创建代理对象
 代理对象的方法体的形成就是目标方法+通知


JDK动态代理和CGLIB字节码生成的区别?
 * JDK动态代理只能对实现了接口的类生成代理,而不能针对类
 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法


Java针对接口的动态代理:

       客户端调用--------->代理对象---------->被调用目标对象.

      动态代理必须实现InvocationHandler接口,同时使用以下方法.

   Object invoke(Objectm代理实例,Method代理实例上调用的接口方法的Method 实例,Object[] 传入代理实例上方法调用的参数值的对象数组);

    Proxy.newProxyInstance(类加载器, Class<?>[]接口数组,回调代理对象(一般是this))

public class MyInvocationHandler implements InvocationHandler {      private Object target;        MyInvocationHandler() {          super();      }        MyInvocationHandler(Object target) {          super();          this.target = target;      }      @Override      public Object invoke(Object o, Method method, Object[] args) throws Throwable {          if("getName".equals(method.getName())){              System.out.println("++++++before " + method.getName() + "++++++");              Object result = method.invoke(target, args);              System.out.println("++++++after " + method.getName() + "++++++");              return result;          }else{              Object result = method.invoke(target, args);              return result;          }        }  }  
---

public class Main1 {      public static void main(String[] args) {          UserService userService = new UserServiceImpl();          InvocationHandler invocationHandler = new MyInvocationHandler(userService);          UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),                  userService.getClass().getInterfaces(), invocationHandler);          System.out.println(userServiceProxy.getName(1));          System.out.println(userServiceProxy.getAge(1));      }  }

运行结果

++++++before getName++++++
------getName------
++++++after getName++++++
Tom
------getAge------
10

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

nginx:
    Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器
    特点:
        反向代理 负载均衡 动静分离...
    反向代理 :
        先来了解正向代理:需要我们用户,手动的设置代理服务器的ip和端口号
        反向代理:代理服务器的,用户不需要设置.
        
    负载均衡:
        原理就是数据流量分摊到多个服务器上执行,减轻每台服务器的压力,
        多台服务器共同完成工作任务,从而提高了数据的吞吐量。
    动静分离:
        将静态的资源放到反向服务器,节省用户的访问时间.

////////////////////////////////////////////

用nginx在window上搭建一个集群
    1.在g盘新建两个目录 tomcat1 tomcat2
    2.修改tomcat2的端口 在tomcat1的端口上+10
    3.解压nginx
        修改nginx的 nginx.conf文件
        在locatioin / 下添加了反向代理
            proxy_pass 代理服务器
        这是只是代理一台服务器
    4.代理集群
        需要在http节点上添加一个
            upstream servlet_yujia{
                server 127.0.0.1:8080;
                server 127.0.0.1:8090;
            }
        修改location /下的反向代理
            proxy_pass http://servlet_yujia
    5.session共享问题
        解决方式1:只能在window下好使
            web服务器解决(广播机制)
            注意:tomcat下性能低
            修改两个地方:
                1.修改tomcat的server.xml 支持共享
                    将 引擎标签下的
                        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
                    注释去掉
                2.修改项目的配置文件 web.xml中添加一个节点
                    
        解决方式2:
            可以将session的id放入redis中
        解决方式3:
            保证一个ip地址永远的访问一台web服务器,就不存在session共享问题了,在linux
            在nginx的配置文件中
                upstream中添加 ip_hash;
        
////////////////////////////////////////////
在linux搭建集群
    1.先将 nginx上传到linux上
    2.解压nginx
    3.先编译nginx
        安装依赖包
            yum install gcc-c++
            yum install -y pcre pcre-devel
            yum install -y zlib zlib-devel
            yum install -y openssl openssl-devel
        执行编译
            先进入 nginx的目录
            执行
                ./configure
        
    4.安装nginx
        执行
            make
            make install
    5.启动nginx
        cd nginx目录下
            配置文件 conf
            启动nginx
                ./nginx
    6.将端口号80 放行
        /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
        将该设置添加到防火墙的规则中
        /etc/rc.d/init.d/iptables save
    7.修改conf文件 和window下一样
        配置集群

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

redis相比memcached的好处

1.memecached的值均是简单字符串,而redis支持string list set' hash等多种类型

2.redis可以持久化其数据而放在硬盘,而memcached掉电后就没有了

-------------------------------------------------------------------------------------------------------------------

Redis

1. 什么是redis
    redis是一个nosql(not only sql不仅仅只有sql)数据库.翻译成中文叫做非关系型型数据库.
    关系型数据库:以二维表形式存储数据
    非关系型数据库: 以键值对形式存储数据(key, value形式)
    是一家意大利的创业公司出的,然后后来这家公司被VMware赞助. redis底层用C语句编写.
    
    redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中,
    redis优点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件.
    缺点:对持久化支持不够良好,
    所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用.

2. redis应用领域
    分布式缓存
    分布式session
    保存博客或者论坛的留言回复等.
    总之是用在数据量大,并发量高的情况下

3. 怎么用
    redis主要就是使用命令来进行操作,java端在代码中可以使用Jedis来操作redis服务器
    redis数据类型
   1.字符串类型,2.散列类型 3.列表类型 4.集合类型 5.有序集合类型

   Redis五种数据类型介绍     
4.redis持久化方案:
    rdb(Redis DataBase):可以设置间隔多长时间保存一次(Redis不用任何配置默认的持久化方案)
        优点:让redis的数据存取速度变快
        缺点:服务器断电时会丢失部分数据(数据的完整性得不到保证)
    aof:(Append-only file)可以设置实时保存
        优点:持久化良好,能包装数据的完整性
        缺点:大大降低了redis系统的存取速度
5. 主从复制:    
    这里使用了心跳检测机制,主从复制必须使用rdb持久化方式
    从服务器一般是只读的,保证主服务器和从服务器的数据一致性

6.Redis设置过期时间

  1. EXPIRE 将key的生存时间设置为ttl秒
  2. PEXPIRE 将key的生成时间设置为ttl毫秒
  3. EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
  4. PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳

-------------------------------------------------------------------


-------------------------------------------------------------------


--------------------------------------------------------------------


----------------------------------------------------------------------


--------------------------------------------------------------


-------------------------------------------------------------

0 0