• 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进行配置

         

             

              

        

         

           

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

  • 相关阅读:
    druid 配置监控界面和开启spring支持
    关于ComboGrid取值为非下拉框数据是,隐藏面板数据清空
    Error:Execution failed for task ‘:app:processDebugManifest’.
    The newly created daemon process has a different context than expected
    在CentOs6.5下安装Python2.7.6和Scrapy
    【转】Ehcache详细解读
    项目代码的缺陷
    hibernateTemplate
    java.text.SimpleDateFormate错误
    关于集合的空指针问题
  • 原文地址:https://www.cnblogs.com/fupengpeng/p/6890522.html
Copyright © 2020-2023  润新知