----------------------------------------------------------
----------------------------------------------------------
-----------------------------------------------------------
-------------------------------------------------------------
-----------------------------------------------------------------
-------------------------------------------------------------------
-----------------------------------------------------------------
-------------------------------------------------------------------
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
资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。
一般使用时还是post和get。Put和Delete几乎不使用。
----------------------------------------------------------------------------------
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不存在
---------------------------------------------------------------------------------------------------------
MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,
但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。
------------------------------------------------------------------
      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只要一行代码就可以搞定。
---------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
跨域问题解决方案(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响应到客户端浏览器.
-------------------------------------------------------------------------
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。
-----------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
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语句去数据库查询(并存入相应的一级缓存,二级缓存并返回)
--------------------------------------------------------------------------------------------------------------------
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=""		-Exception
				no-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设置过期时间
- EXPIRE 将key的生存时间设置为ttl秒
 - PEXPIRE 将key的生成时间设置为ttl毫秒
 - EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
 - PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳
 
-------------------------------------------------------------------
-------------------------------------------------------------------
--------------------------------------------------------------------
----------------------------------------------------------------------
--------------------------------------------------------------
-------------------------------------------------------------

京公网安备 11010502036488号