zoukankan      html  css  js  c++  java
  • Spring学习笔记

    Spring 的控制反转:把对象的创建、初始化、销毁等工作交给Spring 容器来做,有spring容器控制对象的生命周期

     

    applicationContext.xml

    beans --->spring 容器中的类

    alias—>取别名

     

    不管有继承关系(不管有几层)先把当前类加载到虚拟机中才能创建对象,而在加载过程中,静态代码块(static )就一块执行了。所以

    现在子类静态代码快赋值,在父类中(@before)接受并使用该值

    无论两个类之间有什么继承关系,今天代码块比方法先执行。

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

    在默认情况下,Spring创建bean是单例模式,属性是共享的(线程安全问题)

    bean scope属性--->singleton(单例,共享,默认)一般情况下,把数据存放在方法中的变量中,尽量别放在类的属性中prototype(多例) 当一个bean是多例模式下,lazy-init为false或者default无效

     

    init-method
                         * 该方法是由spring容器执行
                         * 在构造函数之后执行
                         * 如果在构造函数之后,在调用方法之前要做一些工作,可以在init方法中完成
    destroy-method
                         * 如果该bean是单例,则在spring容器关闭或者销毁的时候,执行该方法
                         * 如果该bean是多例,则spring容器不负责销毁
                       说明:要想让spring容器控制bean的生命周期,那么该bean必须是单例
                                  如果该bean是多例,该bean中还有资源,关闭资源的操作由程序员完成

    在启动spring容器的时候,spring容器配置文件中的类就已经创建完成对象了
                    lazy-init
                       default  false
                       true  在context.getBean的时候才要创建对象
                          *  优点
                                        如果该bean中有大数据存在,则什么时候context.getBean,什么时候创建对象
                                        可以防止数据过早的停留在内存中,做到了懒加载
                          *  缺点
                                         如果spring配置文件中,该bean的配置有错误,那么在tomcat容器启动的时候,发现不了
                       false 在启动spring容器的时候创建对象
                          *  优点
                                         如果在启动tomcat时要启动spring容器,
                                         那么如果spring容器会错误,这个时候tomcat容器不会正常启动
                          *  缺点
                                          如果存在大量的数据,会过早的停留在内存中

    DI(依赖注入):给属性赋值 person类中name;

    eg、

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        <bean id="person" class="cn.itcast.spring0909.di.xml.set.Person">
            <!--
                property就是代表属性
                  在spring中基本类型(包装类型和String)都可以用value来赋值
                                         引用类型用ref赋值

             -->
            <property name="pid" value="5"></property>
            <property name="pname" value="王二麻子"></property>
            <property name="student">
                <ref bean="student"/>
            </property>
            <property name="lists">
                <list>
                    <value>list1</value>
                    <value>list2</value>
                    <ref bean="student"/>
                </list>
            </property>
            <property name="sets">
                <set>
                    <value>set1</value>
                    <value>set2</value>
                    <ref bean="student"/>
                </set>
            </property>
            <property name="map">
                <map>
                    <entry key="map1">
                        <value>map1</value>
                    </entry>
                    <entry key="map2">
                        <value>map2</value>
                    </entry>
                    <entry key="map3">
                        <ref bean="student"/>
                    </entry>
                </map>
            </property>
            <property name="properties">
                <props>
                    <prop key="prop1">
                        prop1
                    </prop>
                </props>
            </property>
        </bean>
        <bean id="student" class="cn.itcast.spring0909.di.xml.set.Student"></bean>
    </beans>

    构造函数:

    <bean id="person" class="cn.itcast.spring0909.di.xml.constructor.Person">
            <!--
                构造函数的参数
                  index  第几个参数,下标从0开始
                  type   参数的类型
                  ref    如果类型是引用类型,赋值
                  value  如果类型是基本类型,赋值
                 说明:
                    只能指定一个构造函数
             -->
            <constructor-arg index="0"  type="java.lang.String" value="干露露"></constructor-arg>
            <constructor-arg index="1"  ref="student"></constructor-arg>
        </bean>

    IOC和DI做了什么事情:

    1、创建对象

    2、为对象的属性赋值

    意义在于:可以在一个类引用一个接口,而给接口赋值的工作交给spring容器来做,程序员只需在配置文件作相应的配置就好了,这样客户端就可以完全的面向接口的编程。

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

    annotation

    @Resource注解

    原理
    *    *  启动spring容器,并且加载配置文件
    *    *  会为student和person两个类创建对象
    *    *  当解析到<context:annotation-config></context:annotation-config>
    *       会启动依赖注入的注解解析器
    *    *  会在纳入spring管理的bean的范围内查找看哪些bean的属性上有@Resource注解
    *    *  如果@Resource注解的name属性的值为"",则会把注解所在的属性的名称和spring容器中bean的id进行匹配
    *       如果匹配成功,则把id对应的对象赋值给该属性,如果匹配不成功,则按照类型进行匹配,如果再匹配不成功,则报错
    *    *  如果@Resource注解的name属性的值不为"",会把name属性的值和spring容器中bean的id做匹配,如果匹配
    *       成功,则赋值,如果匹配不成功 ,则直接报错
    * 说明:
    *    注解只能用于引用类型,如果一个类中有基本数据类型(long int String),并且基本类型使用Spring的形式赋值的,这个时候,该类必须用xml进行赋值(在javaweb中很少直接赋值,大多数都是从服务器获取值)

    @component注解

    原理
    *   *  启动spring容器,加载配置文件
    *   *  spring容器解析到
    *         <context:component-scan base-package="cn.itcast.spring0909.scan"></context:component-scan>
    *   *  spring容器会在指定的包及子包中查找上是否有@Component
    *   *  如果@Component注解没有写任何属性
    *        @Component
    *        public class Person{
    *       
    *        }
    *        ==
    *        <bean id="person" class="..Person">
    *      如果@Component("aa")
    *        @Component
    *        public class Person{
    *       
    *        }
    *        ==
    *        <bean id="aa" class="..Person">
    *    *  在纳入spring管理的bean的范围内查找@Resource注解
    *    *  执行@Resource注解的过程
    *  说明:
    *     xml效率比较高,但是书写比较麻烦
    *     注解效率比较低,书写比较简单

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

    <!--
            abstract
              spring容器不会为该类创建对象
         -->
        <bean id="person" class="cn.itcast.spring0909.extend.Person" abstract="true">
            <property name="name" value="王二麻子的哥"></property>
        </bean>

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

    <bean id="person" class="cn.itcast.spring0909.extend.Person" abstract="true">
            <property name="name" value="王二麻子的哥"></property>
        </bean>
        <!--
            parent
              让子类拥有父类的属性的值
         -->
        <bean id="student" class="cn.itcast.spring0909.extend.Student" parent="person">
        </bean>

    代理模式、动态代理  (invoke)

    package cn.itcast.salary.jdkproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    /**
     * 1、把日志、安全性框架、权限导入进去
     * 2、把目标类导入进去
     * 3、上述两类通过构造函数赋值
     * @author Administrator
     *
     */
    public class SalaryInterceptor implements InvocationHandler{
        
        private Logger logger;
        private Security security;
        private Privilege privilege;
        
        private Object target;
        
        public SalaryInterceptor(Logger logger,Security security,Privilege privilege,Object target){
            this.logger = logger;
            this.security = security;
            this.privilege = privilege;
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            // TODO Auto-generated method stub
            System.out.println("aaaaaa");
            this.logger.logging();
            this.security.security();
            if("admin".equals(this.privilege.getAccess())){
                //调用目标类的目标方法
                method.invoke(this.target, args);
            }else{
                System.out.println("您没有该权限");
            }
            System.out.println("bbbbbb");
            return null;
        }
    
    }
    客户端
    public void test(){
            Logger logger = new Logger();
            Privilege privilege = new Privilege();
            privilege.setAccess("admin");
            Security security = new Security();
            SalaryManager target = new SalaryManagerImpl();
            SalaryInterceptor interceptor = new SalaryInterceptor(logger, security, privilege, target);
            /**
             * 1、目标类的类加载器
             * 2、目标类的所有的接口
             * 3、拦截器
             */
             SalaryManager proxy = (SalaryManager) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
             proxy.showSalary();//代理对象的代理方法
        }

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

    image

    image

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

    AOP

    image

    捕获

     

    说明:

    * 切面

    日志、安全性的框架、权限的检查等,总之和业务逻辑没有关系的都可以看做切面

    * 通知

    切面中的方法

    * 切入点

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

    * 连接点

    客户端调用的方法

    * 代理对象的方法=通知+目标方法

    * aop:做到了代码块的重用

     

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/aop 
               http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
        <!-- 
            1、引入AOP的命名空间
            2、目标类
            3、切面
            4、拦截器  由spring内部实现
            5、aop的配置
         -->
        <bean id="personDao" class="cn.itcast.spring0909.aop.xml.PersonDaoImpl"></bean>
        <bean id="transaction" class="cn.itcast.spring0909.aop.xml.Transaction"></bean>
        <!-- 
            aop的配置
         -->
        <aop:config>
            <!-- 
                切入点表达式
                  expression
                         确定哪个类可以生成代理对象
                  id  唯一标识 
             -->
            <aop:pointcut expression="execution(* cn.itcast.spring0909.aop.xml.PersonDaoImpl.*(..))" id="perform"/>
            <!-- 
                切面
             -->
             <aop:aspect ref="transaction">
                 <!-- 
                     前置通知
                  -->
                 <aop:before method="beginTransaction" pointcut-ref="perform"/>
                 <aop:after-returning method="commit" pointcut-ref="perform"/>
             </aop:aspect>
        </aop:config>
    </beans>

     

    QQ截图20150401220728

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

    <aop:config>
            <!-- 
                切入点表达式
                  expression
                         确定哪个类可以生成代理对象
                  id  唯一标识 
             -->
            <aop:pointcut expression="execution(* cn.itcast.spring0909.aop.xml.PersonDaoImpl.*(..))" id="perform"/>
            <!-- 
                切面
             -->
             <aop:aspect ref="transaction">
                 <!-- 
                     前置通知
                       *  在目标方法执行之前
                       *  
                  -->
                  <!-- 
                 <aop:before method="beginTransaction" pointcut-ref="perform"/>
                  -->
                 <!-- 
                     后置通知
                       *  在目标方法执行之后
                       *  可以根据returning获取目标方法的返回值
                       *  如果目标方法遇到异常,该通知不执行
                  -->
                  <!-- 
                 <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
                  -->
                <!-- 
                    前置通知和后置通知只能在目标方法文中添加内容,但是控制不了目标方法的执行
                 -->
                 <!-- 
                     最终通知
                        *  在目标方法执行之后
                        *  无论目标方法是否遇到异常,都执行
                        *  经常做一些关闭资源
                  -->
                  <!-- 
                 <aop:after method="finallyMethod" pointcut-ref="perform"/>
                  -->
                 <!-- 
                     异常通知
                        目的就是为了获取目标方法抛出的异常
                  -->
                  <aop:after-throwing method="exceptionMethod" throwing="ex" pointcut-ref="perform"/>
                  <!-- 
                      环绕通知
                         能控制目标方法的执行
                   -->
                  <aop:around method="aroundMethod" pointcut-ref="perform"/>
             </aop:aspect>
        </aop:config>

    AOP总结:

    * 原理
    *    *  加载配置文件,启动spring容器
    *    *  spring容器为bean创建对象
    *    *  解析aop的配置,会解析切入点表达式
    *    *  看纳入spring管理的那个类和切入点表达式匹配,如果匹配则会为该类创建代理对象
    *    *  代理对象的方法体的形成就是目标方法+通知
    *    *  客户端在context.getBean时,如果该bean有代理对象,则返回代理对象,如果没有代理对象则返回原来的对象
    * 说明:
    *    如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用
    *      cglibproxy

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

    Struts2

    问题:

    * action是单例还是多例?怎么样证明?

    Action是多例的,在构造函数中输出一句话,如果请求好几次,只输出一次,单例

    如果请求很多次,输出很多次,多例

    * struts2有三个类

    ActionContext

    ServletActionContext 建立struts2与servlet的通信的桥梁

    ActionInvocation struts2总的上下文

    * struts2的数据都在值栈中,怎么样保证数据的安全性?值栈的生命周期是什么?

    因为ValueStack在ActionContext中,而ActionContext在ThreadLoad中,所以可以保证数据的安全性

    值栈的生命周期是一次请求,当前的action,actioncontext,valuestack的生命周期是一致的

    image

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

    image

    image

  • 相关阅读:
    APK: 开机自启
    Android Button 三种监听方式
    unity 获取Project面板已选择资源的路径
    unity 自定义Project面板右键菜单
    unity Mathf.Atan2()
    unity/C# 通过反射调用对象的私有方法
    Unity WebGL 去除移动端的警告
    Unity Shader 序列帧动画
    Unity Shader 3种精度的数值类型
    Unity Shader Unity支持的语义
  • 原文地址:https://www.cnblogs.com/NeilLing/p/4386380.html
Copyright © 2011-2022 走看看