spring框架总结

---恢复内容开始---

spring框架主要核心的部分分为两个部分:

        aop:面向切面编程 不通过修改源代码,对功能进行扩张增强

     ioc:控制反转      通常我们建立对象都是通过new的形式进行创建对象,但是我们这里是通过交给spring来进行创建对象

  什么是spring?

        spring为一个开源轻量级框架   他是一个一站式框架  对javeee的3层结构都提供了不同的技术 

  有什么用?

        具体的用法分为ioc与aop两个方面

       ioc的底层原理:

             配置xml文件

           dom4J进行解析

               得到class路径也就是名称

              通过Class类的newinstance方法创建对象

          spring的bean管理(配置xml文件方式)

                  bean的实例化有3个方面

                        1.通过无参构造函数进行

                        2.通过静态工厂来进行创建

                                   

 <bean id="factory" class="com.jdztc.ioc.Factory" factory-method="getUser"></bean>

  getUser为com.jdztc.ioc.Factory类中的静态方法得到对象

                          3.通过实例工厂来进行创建(就是创建对象的方法不是静态方法)

    首先需要进行对对象的创建否则将不能轻松的调用getUser方法

<bean id="factoryshili" class="com.jdztc.bean.FactoryShiLi" ></bean>
        <bean id="bean2" factory-bean="factoryshili" factory-method="getUser"></bean>

  

scope属性的介绍:

         他为bean的作用范围

             默认值为singleton  为单实例对象

             prototype:为多实例对象

             request:创建对象把对象放入request中

             session:创建对象把对象放入sesison中

             gobleSession:创建对象把对象放入session中    具体应用:百度首页登录一次其他应用都可以使用

属性注入介绍:

          向对象中的属性注入值

          有3种方式:1.set方法进行注入(用的最多)

<bean id="user1" class="com.jdztc.type.User"><property name="username" value="你好"></property></bean>

 

                         <property></property>

                           2.有参构造函数

 

<!-- 属性注入(构造方法) -->
        <bean id="user2" class="com.jdztc.type.UserConstructor">
               <constructor-arg name="username" value="你好"></constructor-arg>
        </bean>

 

                              <constructor-arg>标签

                           3接口注入方式(不支持) 

              注入复杂类型属性:

                  注入对象类型属性:(用的最多)

                             

 <!-- 注入对象类型属性 -->
        <bean id="dao" class="com.jdztc.type.UserDao"></bean>
        <bean id="service" class="com.jdztc.type.UserService">
            <property name="userDao" ref="dao"/>
        </bean>

                      P名称空间注入(一个标签不能多个相同的属性)

               

xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.jdztc.type.Person" p:pname="你不好">

                 注入arr数组  list集合   map集合   properties集合

                   arr数组的注入方式很相似

                        <list><value></value><l/ist>形式有多少个值就有多少个value

                    map集合

                         <map><entry key="" vlaue=""></entry></map>

                   properties

                           <props><prop key="">你好</prop></props>

                           ioc与dI的区别

                                    ioc:对象的创建交给spring来创建

                                    DI:依赖注入    给对象中的属性注入值

                                    DI不能单独存在  ,他是建立在ioc的基础之上的

                           spring整合项目原理

                          核心配置文件的加载和对象的创建交给服务器来创建,也就是在服务器加载的时候创建

                          用到的ServletContext和监听器

                              在web.xml文件中配置   

 <!--配置监听器 -->
    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

 

  

<!--指定spring配置文件  -->
	<context-param>
	  <param-name>contextConfigLocation</param-name>
	  <param-value>classpath:spring2.xml</param-value>
	</context-param>

                     原理:使用监听器听到ServletContext创建时,进行了以下操作

                                1:加载核心配置文件,创建配置文件的对象

                                2.把配置文件的对象放入servletContext中  setAttribute()方法

                                 3.获取配置文件对象    getAttribute()

       spring的bean管理方式(注解方式实现)

                         导入aopjar包

                          开启注解扫描

                        对类.方法.属性都进行扫描

                          <context:component-scan>

                         只对类的属性

                          <context:annotation-config>

                          注解创建对象

                             @component(value="对象名")

                             @controller(value="")  web层

                             @service                 service层            功能是一致的都能创建对象

                             @Repository            持久层

                @scope配置范围   是单实例还是多实例对象

                            注解注入属性

                                     @AutoWired  不需要set方法和类的注解的value值无关   主要是根据属性来找

                                    @Resource   value值要与类的注解的vlaue保持一致

      aop方面:

                                        

                           原理:1.不修改原代码进行对功能的扩展2.采用横向抽取机制 

                     横向抽取机制与纵向抽取机制

                    纵向抽取:

                 

public  class Fu{
      publci void add(){
}
}
public Class Zi extends Fu{
       public void add(){
        super.add()
}
            
}

       横向抽取机制

      底层使用动态代理实现

              动态代理分为:

               jdk动态代理针对有接口的情况

               原理:创建接口实现类的代理对象(实现InvocationHandler接口),这个对象有着与实现类相同的功能

             

package com.jdztc.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 针对有接口的情况,使用jdk的动态代理
 * @author 付鹏鹏
 *
 */
interface Fuu{
	public void add();
}
public class ZhongXiangChouQuDemo implements Fuu{

	//要增强的方法即切入点
	@Override
	public void add() {
		// TODO Auto-generated method stub
		//实现快速的拉屎   增强拉屎的功能
        System.out.println("拉屎");		
	}

}
/**
 * 创建与实现类相同功能的代理类
 * @author 付鹏鹏
 *
 */
class FuuProxy implements InvocationHandler{

	private ZhongXiangChouQuDemo zhongxiang;
	/**
	 * 覆盖其默认构造函数
	 */
	public FuuProxy(ZhongXiangChouQuDemo zhongxiang) {
		this.zhongxiang = zhongxiang;
	}
	/**
	 * 生成实现类相同功能的代理对象
	 */
	public Object getProxy(){
		return Proxy.newProxyInstance(zhongxiang.getClass().getClassLoader(), zhongxiang.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		Object result=null;
		System.out.println("事物的开启");
		result=method.invoke(zhongxiang, args);
		System.out.println("事物的结束");
		return result;
	}
	
	
}

  具体的调用    

//创建jdk动态代理类
		/*ZhongXiangChouQuDemo zhongxiang=new ZhongXiangChouQuDemo();
		FuuProxy proxy=new FuuProxy(zhongxiang);
		Fuu fuu=(Fuu) proxy.getProxy();
		fuu.add();*/

         cglib动态代理  针对没有接口的情况下

              原理:创建子类代理对象与子类有着相同的功能(实现methodInterceptor)

package com.jdztc.aop;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import javassist.util.proxy.MethodHandler;

/**
 * 没有接口的情况下  使用cglib动态代理
 * @author 付鹏鹏
 *
 */
class Dao{
	public void add(){
		System.out.println("拉屎");
	}
}
public class CglibProxyDemo extends Dao{
    public void add(){
    	System.out.println("拉屎");
    }
}
/**
 * 创建子类的代理对象
 * @author 付鹏鹏
 *
 */
class CglibProxy implements MethodInterceptor{
	private Object terget;
	public CglibProxy(Object terget) {
		this.terget = terget;
	}
	public Object getIntercept(){
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(terget.getClass());
		//回调方法
		enhancer.setCallback(this);
		//创建对象
		return enhancer.create();
	}
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("食物开启前");
	    arg3.invoke(terget, arg2);
		System.out.println("事务结束了");
		return null;
	}
	
}

  

               具体的调用

         

Dao cglibProxyDemo=new Dao();
		CglibProxy cglibProxy=new CglibProxy(cglibProxyDemo);
		Dao Dao=(Dao) cglibProxy.getIntercept();
	    Dao.add();

   上面两种方式都对方法进行了增强

       aop术语:

         切入点:真正被增强的方法

         增强或通知:你要实现增强的逻辑

              前置增强:在方法执行之前

              后置增强:在方法执行之后

              异常增强:在方法出现异常时执行

              最终通知:在后置之后执行

              环绕执行:在方法之前执行    方法之后执行也会执行

         切面:将增强具体应用到切入点中的过程

         这3个为常用的术语

            连接点:类里面有哪些可以被增强,这些方法就是连接点

           引介:动态的添加方法和属性

           target(目标对象):代理目标(要增强的类)

           wearing(织入):把增强应用到目标对象的过程

           proxy(代理):一个类被aop织入增强后,就产生一个结果代理类

            

      aop操作

    

                基于aspectj的aop操作

                     aspectj是什么?他是面向切面的框架(把动态代理那些功能进行了封装)

               实现方式:

                       1.基于aspectj的xml配置

                       2.基于aspectj的注解

                       引入约束

                          导入jar包spring-aop       spring-aspectj   aopaliance    aspectj-weaver

                       使用表达式配置切入点

                             execution(* cn.itcase.aop.book.add(..))表示配置add切入点

                             execution(* cn.itcase.aop.Book.*(..))表示配置book类中所有的切入点

                            execution(* save*(..))匹配所有以save开头的方法

                       具体的应用

                       首先要创建对象

                    

 <!--创建两个类的对象  -->
        <bean id="book" class="com.jdztc.aspectj.Book"></bean>
        <bean id="mybook" class="com.jdztc.aspectj.MyBook"></bean>

  

                       aop配置

                      配置切入点

                       将增强应用到切入点中

 <!--aop配置  -->
        <aop:config>
        <!--*后要有空格  -->
        <!-- 配置切入点 -->
               <aop:pointcut expression="execution(* com.jdztc.aspectj.Book.*(..))" id="pointcut1"/>
         <!-- 配置切面   把增强应用到方法当中的过程-->
               <aop:aspect ref="mybook">
                     <aop:before method="before1" pointcut-ref="pointcut1"/>
                     <aop:around method="around" pointcut-ref="pointcut1"/>
               </aop:aspect>
        </aop:config>

  

package com.jdztc.dao;

public class Book {

	public void add(){
		System.out.println("add....");
	}
}

      

package com.jdztc.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyBook {

	public void before1(){
		System.out.println("before前置增强...");
	}
	/**
	 * 环绕增强
	 * @throws Throwable 
	 */
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
		System.out.println("方法之前");
        //执行方法
		proceedingJoinPoint.proceed();
		System.out.println("方法之后");
	}
}

  log4j介绍:

              info  只能看到基本信息

             debug  可以看到详细的信息

     基于aspectj的注解aop操作

        1创建对象 2开启aop操作   在增强类中使用   在类的上面使用@Aspectj     在方法的上面使用@Before

         具体的例子

              

<bean id="book" class="com.jdztc.dao.Book"></bean>
       <!--增强类-->
       <bean id="mybook" class="com.jdztc.service.MyBook"></bean>
       <!--开启aop注解操作 -->
       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

  

package com.jdztc.service;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyBook {
//value值为切入点 @Before(value = "execution(* com.jdztc.dao.Book.*(..))") public void before1(){ System.out.println("before1....."); } }

    JDBCTemplate操作和使用

                他与dbutil的使用很相似

                   dbutil操作实现查询要实现ResultSetHanlder

                 QueryRunner runner=new QueryRunner(dataSource);

               查询对象

                 runner.query(sql,new BeanHanlder<User>(User.calss))

                 BeanHanlder为ResuleSetHanlder接口的实现类

 

                 runner.query(sql,new ResultlistHanlder<User>(User.class))

                 ResultListHanlder为ResultSetHanlder接口的实现类

              JdbcTemplate实现查询也实现了接口RowMapper

                     具体的代码:

                  

package com.jdztc.jdbctemplate;



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;





public class JdbcTemplateQuery {

	/**
	 * jdbc模版查询返回list  使用query方法
	 * 
	 */
	@Test
	public void queryList(){
		//创建对象
		DriverManagerDataSource dataSource=new DriverManagerDataSource();
		//设置数据库连接条件
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
		dataSource.setUsername("root");
		dataSource.setPassword("");
		//创建jdbc模版对象
		JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
		String sql="select * from spring_03";
		//调用模版的查询的方法queryForObject方法     
		List<User> list=jdbcTemplate.query(sql,new MyRowMapper());
	    System.out.println(list);
		
		
		
	}
	/**
	 * jdbc模版查询返回对象
	 * 
	 */
	@Test
	public void queryObject(){
		//创建对象
		DriverManagerDataSource dataSource=new DriverManagerDataSource();
		//设置数据库连接条件
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
		dataSource.setUsername("root");
		dataSource.setPassword("");
		//创建jdbc模版对象
		JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
		String sql="select * from spring_03 where id=?";
		//调用模版的查询的方法queryForObject方法     
		User user=jdbcTemplate.queryForObject(sql, new MyRowMapper(), 1);
		System.out.println(user);
		
	}
	/**
	 * 查询有多少条记录
	 * 查询返回某一个值  使用queryForObject方法  他的第二个参数 为返回值类型的字节码文件
	 */
	@Test
	public void testCount(){
		//创建对象
		DriverManagerDataSource dataSource=new DriverManagerDataSource();
		//设置数据库连接条件
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
		dataSource.setUsername("root");
		dataSource.setPassword("");
		//创建jdbc模版对象
		JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
		String sql="select count(*) from spring_03";
		//调用模版的查询的方法queryForObject方法     
		int a=jdbcTemplate.queryForObject(sql,Integer.class);
		System.out.println(a);
		
	}
	/**
	 * jdbc的底层代码
	 */
	@Test
	public void query(){
		Connection connection=null;
		PreparedStatement preparedStatement=null;
		ResultSet rs=null;
		//加载驱动
		try {
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			String url="jdbc:mysql://localhost:3306/spring";
			String user="root";
			String password="";
			connection=DriverManager.getConnection(url, user, password);
			String sql="select * from spring_03 where id=?";
			//预编译sql语句
			preparedStatement=connection.prepareStatement(sql);
			preparedStatement.setInt(1,1);;
			rs=preparedStatement.executeQuery();
			while(rs.next()){
				//System.out.println(rs.next());
				User user1=new User();
				String username=rs.getString("username");
				String password1=rs.getString("password");
				user1.setPassword(password1);
				user1.setUsername(username);
				System.out.println(user1);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				if (connection != null) {
					connection.close();
				}
				if (rs != null) {
					rs.close();
				}
				if (preparedStatement != null) {
					preparedStatement.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
}
class MyRowMapper implements RowMapper<User>{

	@Override
	public User mapRow(ResultSet rs, int arg1) throws SQLException {
		// TODO Auto-generated method stub
		//不需要遍历结果集 这个已在JdbcTemplate中实现了
		User user=new User();
		String username = rs.getString("username");
		String password = rs.getString("password");
		user.setPassword(password);
		user.setUsername(username);
	
		return user;
	}
	
}

  

               c3p0连接池

                    记住这个ComboPooledDataSource对象

                    spring的事务的介绍

                     什么是事务?

                         事务是操作数据库的基本单位    指的是一组操作  这组操作要么都成功要么都失败

                    事务的特性

                         原子性:一组操作要么都成功要么都失败

                        一致型:操作之前之后保持一致

                        隔离性:多个事务操作一个数据,不影响

                        持久性:在数据生效后一直是那样

                    不考虑隔离性产生读问题

                       脏读   不可重复读   还有虚读

                    解决读问题:

                     设置隔离级别

                   事务管理器

                    对象platformTransactionManager

                    spring为不同的持久化技术提供了不同的接口实现

                      jdbcTemplate  和myBatis     DataSourceTransactionManager

                      hibernate5.0  hibernateTranactionManager

                     如何配置事务

                           编程式事务管理(基本不用)

                          声明式事务管理 :

                               1  基于xml配置文件形式实现

                               2   注解方式实现

                       配置步骤:

                            1.配置事务管理器

                            2.配置事务增强

                            3.配置切面(aop操作)

 

                       

<!-- 配置事务管理器 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 配置DataSource属性  与连接池对应 -->
                <property name="dataSource" ref="dataSource"></property>
       </bean>
       
       <!-- 事物增强   根据事物管理器进行事务的增强 -->
       <tx:advice id="aaa" transaction-manager="transactionManager">
           <tx:attributes>
                    <!-- 设置事务操作的方法匹配规则    propagation="REQUIRED"设置事务隔离级别  -->
                    <tx:method name="account*"/>
           </tx:attributes>
       </tx:advice>
       <!-- 配置切面 -->
       <aop:config>
            <!--配置切入点  -->
            <aop:pointcut expression="execution(* com.jdztc.service.OrderService.account(..))" id="pointcut1"/>
            <!-- 将增强应用到切入点中 -->
            <aop:advisor advice-ref="aaa" pointcut-ref="pointcut1"/>
       </aop:config>

       注解方式实现

            

<!-- 配置事务管理器 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 配置DataSource属性  与连接池对应 -->
                <property name="dataSource" ref="dataSource"></property>
       </bean>
       <!-- 开启注解事物 -->
       <tx:annotation-driven transaction-manager="transactionManager"/>

  在你要配置事务的类的上方加上@Transactional  对类中的所有方法加上事务

  

  ssh框架整合思想:

       两个两个进行整合

       struts2对spring框架进行整合

           action对象交给spring进行管理

      spring对hibernate进行整合

          将数据库交给spring进行管理  写到spring的配置文件当中

         创建sessionFactory 交给spring进行配置

     

         

          

 

    

     

       

---恢复内容结束---

posted @ 2017-05-22 17:37  0101无限的空间  阅读(180)  评论(0编辑  收藏  举报