美文网首页
Spring学习笔记

Spring学习笔记

作者: 木栈桥上 | 来源:发表于2017-09-11 17:35 被阅读0次

    在配置好需要的文件后就可以进行编程学习了。。
    Spring基于XML文件配置Bean的方法:
    在IOC容器中配置:

     <beans  ... ...>
     <bean id="helloWorld" class="com.spring.beans.HelloWorld">
     <property name="name" value="spring"></property>     //属性注入
     <property name="sex" value="man"></property>
     <constructor-arg value="spring" ></constructor-arg> //构造器注入
     <constructor-arg value="sex"></constructor-arg>
     <constructor-arg value="spring" index="0"></constructor-arg>  //和上例效果相同
     <constructor-arg value="sex" index="1">
     <constructor-arg value="spring" type="String"></constructor-arg>
     <constructor-arg value="sex" type="String"></constructor-arg>
     </bean>
    </beans>
    

    1.创建spring的IOC容器
    ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
    2.从IOC容器中获取Bean的实例
    HelloWorld helloWorld=(HelloWorld)ctx.getBean(HelloWorld.class); //只能有一个HelloWorld类型的Bean

    HelloWorld helloWorld=ctx.getBean("helloWorld");

    属性配置细节
    1.当要给变量赋值特殊符号时可用<![CDATA["赋值内容"]]>包裹起来。
    2.属性值也可以用 value 直接点进行配置
    3.可以使用property的 ref 属性建立 bean之间的引用关系。
    4.内部 Bean 不能被外部影响,只能内部使用。
    5.可以使用 <null/> 标签为某些属性注入 null 值
    6.使用级联属性赋值时,必须先初始化后才可以为级联属性赋值,当前 Bean 内必须有 get和set -ref对象的方法。
    7.使用<list>标签时,若引用的 Bean 是另一个包里的同名类,则应 import 另一个包的该同名类。
    8.使用 util 标签来配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间。
    9.使用 P命名空间为 bean 的属性赋值,需要导入p命名空间。相对于传统的方式更加简洁。
    格式 : <bean id="person" class="com.spring.beans.Person" p:name="name" p:age="15" ></bean>
    10.可以使用 autowire 自动装配,有byName,byType,constructor等方式。
    <bean id="person" class="com.spring.beans.autowire.Person"
    autowire="byName">
    </bean>
    11.bean之间的关系:bean 可以继承 (parent)、依赖(depends-on),bean的abstract属性为true,这样的bean不能被IOC容器实例化,只用来被继承配置
    不会继承 bean 的所有属性,例如:autowire、abstract……若某一个bean的 class 属性没有指定,则该 bean 必须是一个抽象 bean。
    depends-on 属性会将 前置依赖的Bean在本Bean实例化之前创建好。如果依赖于多个Bean,则可以通过 逗号、空格 配置Bean的名称。
    12.Bean的作用域 : 可以用 scope 属性配置。 singleton 是默认值,容器初始时创建实例,在整个容器生命周期内至创建这一个 bean。 prototype 是原型的,容器初始化时不创建 bean 的实例,而是在每次请求时创建新的 bean实例并返回。
    13.可以使用外部属性文件配置Bean。<context:property-placeholder location="classpath: db.source" /> <property name="user" value="${user}">.
    14.SpEL : 可以使用 SpEL 来给 Bean 配置 。
    (1) 当要给 字符串类型赋值时 : value="#{'abc'}"
    (2) 当赋 整型、浮点型时 : value="#{14}" value="#{123.321}"
    (3) 当引用其他 属性时 : value="#{car}" value="#{car.price}"
    (4) 当引用类的静态属性时: value="#{T(java.lang.Math).PI*8}"
    (5) 当使用运算符时: value="#{ 10>5? '大于' : '小于' }"

    1. 可以自行设置 Bean 的 init()方法 和 destroy() 方法。 先在 Bean Class 里将init()和destroy()方法写好,名字自订,然后在xml文件里配置。
      例:

      <bean id="person" class="com.spring.beans.Person" init-method="init3" destroy-method="destroy"></bean>
      

    16.可以添加 Bean后置处理器。通过写一个 BeanPostProcessor 接口类,然后在里面重写 postProcessAfterInitialization(init后执行)和postProcessBeforeInitialization(init前执行) 方法,并在xml文件里配置。
    例:

     <bean class="com.spring.beans.MyBeanPostProcessor"></bean>
    

    17.可以使用静态工厂方法配置bean:先创建一个静态工厂方法类,例:

    public class StaticGameFactory {
    private static Map<String,Game> games=new HashMap<String,Game>();
    static{
        games.put("ChiJi", new Game("ChiJi",98));
        games.put("H1Z1", new Game("H1Z1",68.0));
    }
    //静态工厂方法
    public static Game getGame(String name){
        return games.get(name);
    

    然后在xml文件里通过静态工厂方法来配置bean。
    例:

      <bean id="game" class="com.spring.beans.factory.Game" factory-method="getGame">
    <constructor-arg value="cf"></constructor-arg></bean>    //如果工厂方法需要传入参数,则使用constructor-arg来配置参数
    

    18.也可以使用实例工厂方法配置bean:

    public class InstanceGameFactory {
    private Map<String,Game> games;
    public InstanceGameFactory(){
        games=new HashMap<String,Game>();
        games.put("CF", new Game("CF",0));
        games.put("dnf", new Game("dnf",1));
    }
    public Game getGame(String name){
        return games.get(name);
    }
    

    需要先配置工厂的实例:

    <bean id="gameFactory" class="com.spring.beans.factory.InstanceGameFactory"></bean>
    

    然后再配置 bean 实例: //factory-bean 指向实例工厂方法的bean factory-method指向实例工厂方法的名字; 如果工厂方法需要传入参数,则使用constructor-arg来配置参数

    <bean id="game2" factory-bean="gameFactory" factory-method="getGame"><constructor-arg value="CF"></constructor-arg></bean>
    

    19.通过FactoryBean 来配置 bean。 首先自定义FactoryBean,需要实现FactoryBean 接口,然后在xml文件里 通过 FactoryBean 来配置Bean的实例,例:
    class:指向FactoryBean的全类名;property:配置FactoryBean的属性; 实际返回的是 FactoryBean 的 getObejct() 方法的实例

    <bean id="game" class="com.spring.beans.factorybeans.GameFactoryBean">
        <property name="name" value="qwe"></property>
    </bean>
    

    20.通过注解配置Bean

    <!-- 指定Spring IOC 容器扫描的包 -->
    <!-- context:component-scan 子节点base-package="" 指定扫描该包及其子包 -->
    <!-- 可通过 resource-pattern 指定扫描的资源 -->
    <!-- 
    <context:component-scan base-package="com.spring.beans.annotation"
        resource-pattern="repository/*.class"
    ></context:component-scan>
    -->
    <!-- context:exclude-filter 子节点指定不包含哪些表达式的组件 -->
    <!-- context:include-filter 子节点指定包含那些表达式的组件,该节点需要use-default-filters 配合使用(use-default-filters="false")-->
    <context:component-scan base-package="com.spring.beans.annotation"
        use-default-filters="true"><!-- type="annotation" 是扫描base-package 包及其所有子包-->
         
    <!--
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
     -->
          <!-- type="assignable" 是扫描指定类及implements它的类 -->
     <context:exclude-filter type="assignable" expression="com.spring.beans.annotation.repository.UserRepository" />
    </context:component-scan>
    

    使用@Autowired自动装配Bean
    一般情况下,所有使用@Autowired注解的属性都要被设置,当Spring找不到匹配的Bean时,会抛出异常,若某一属性允许不被设置,可以设置@Autowired 注解的 required 属性 为fasle。
    默认情况下,当IOC容器里存在多个类型兼容的 Bean 时,通过类型的自动装配将无法工作,此时可以在 @Qualifier 注解里提供 Bean 的名称,Spring 允许对方法的形参标注 @Qualifier 以指定注入 Bean 的名称。
    --@Autowired 注解也可以应用在 数组类型 的属性上,此时Spring 会把所有匹配的 Bean 进行自动装配。
    --@Autowired 注解也可以应用在 集合属性 上,此时Spring 读取该集合的类型信息,然后自动装配所有与之兼容的 Bean。
    --@Autowired 注解用在 java.util.Map 上时,若该 Map 的键值为 String ,那么 Spring 将自动装配与之 Map 值类型兼容的 Bean ,此时Bean 的名称作为键值。

    21.泛型依赖输入

    public class BaseService<T> {
    @Autowired
    private BaseRepository<T> baseRepository;
    public void add(){
        System.out.println("add...");
        System.out.println(baseRepository);
    }
    }
    @Service
    public class UserService extends BaseService<User>{
    }
    @Repository
    public class UserRepository extends BaseRepository<User>{
    }
    

    当 userService 调用 add 方法时,会输出
    add...
    com.spring.beeans.generic.di.UserRepository@2449a2da
    22.动态配置(AOP基础):

    public class ArithmeticCalculatorLoggingProxy {
    //要代理的对象
    private ArithmeticCalculator target;
    public ArithmeticCalculatorLoggingProxy (ArithmeticCalculator target) {
        this.target=target;
    }
    public ArithmeticCalculator getLoggingProxy(){
        //要代理的对象
        ArithmeticCalculator proxy ;
        //代理对象由哪一个类加载器负责加载
        ClassLoader loader= target.getClass().getClassLoader();
        //代理对象的类型,即其中有哪些方法
        Class[] interfaces=new Class[]{ArithmeticCalculator.class};
        //当调用代理对象其中的方法时,该执行的代码
        InvocationHandler h=new InvocationHandler() {
           @Override
           /*
            * proxy:正在返回的那个代理对象,一般情况下,在 invoke 方法中都不使用该对象
            * method:正在被调用的方法
            * args:调用方法时,传入的参数
            */
           public Object invoke(Object proxy, Method method, Object[] args)
                   throws Throwable {
               System.out.println("invoke...");
               //日志
               System.out.println("The method "+method.getName()+" begins with "+Arrays.asList(args));
               //执行方法
               Object result=method.invoke(target, args);
               //日志
               System.out.println("The method "+method.getName()+" ends with "+result);
               return result;
           }
        };
        proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
        return proxy;
      }
    }
      public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
    public int add(int i, int j) {
        return i+j;
    }
    public int sub(int i, int j) {
        // TODO Auto-generated method stub
        return i-j;
    }
    public int mul(int i, int j) {
        // TODO Auto-generated method stub
        return i*j;
    }
    public double div(double i, double j) {
        return i/j;
    }
    }
    public class Main {
    public static void main(String[] args) {
    ArithmeticCalculator target=new ArithmeticCalculatorImpl();
    ArithmeticCalculator proxy=new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();
    
    System.out.println(proxy.getClass().getName());
    
    int result=proxy.add(1, 2);
    System.out.println(result);
    
    result=proxy.sub(3, 1);
    System.out.println(result);
    }
    }  
    

    输出结果为:
    com.sun.proxy.$Proxy0
    invoke...
    The method add begins with [1, 2]
    The method add ends with 3
    3
    invoke...
    The method sub begins with [3, 1]
    The method sub ends with 2
    2
    23.(1)SpringAOP
    ①加入JAR包 ②在配置文件中加入 aop 的命名空间
    ③基于注解的方式:
    i.在配置文件中加入如下配置:

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <bean class="Aspect.class" /  >
     <!--扫描AOP和代理对象的类-->
     <context:component-scan base-package="com.aop" />
    

    AOP类:

    @Aspect
    public class LogginPerformance {
       @Pointcut("execution(** com.aop.Performance.perform(..))")
       public void cut() {}
       
       @Before("cut()")
       public void beforeMethod() {
             System.out.println("Before");
       }
    }
    

    代理对象类:

    package com.aop;
    public interface Performance {
         public void perform();
    }
    

    还需要讲implements 该接口类的 类 加入扫描对象

    package com.aop;
    @Component
    public class Singer implements Performance{
    @Override
    public void perform() {
        System.out.println("唱歌");
    }
    }
    

    使用方法:

    package com.aop;
    @Component
    public class TestAOP {
    public static void main(String[] args) {
       ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
       Performance p=ctx.getBean(Performance.class);
       p.perform();
    }
    }
    

    相关文章

      网友评论

          本文标题:Spring学习笔记

          本文链接:https://www.haomeiwen.com/subject/khmfsxtx.html