zoukankan      html  css  js  c++  java
  • Spring4 笔记

    1. 通过 xml 赋值给 bean  

    1) 通过set 方法赋值 (必须要有空的构造方法) 

      <bean id="user" class="com.test.User">
        <property name="name" value="张三"></property>
        <property name="age" value="20"></property>
        <property name="address" value="北京"></property>
      </bean>

    2) 通过构造方法赋值  

      <bean id="user2" class="com.test.User">
        <constructor-arg value="李四"></constructor-arg>
        <constructor-arg value="20"></constructor-arg>
        <constructor-arg value="上海"></constructor-arg>
      </bean>

      

      3) 装配 list 属性 (实体类中必须先定义好list)

      <bean id="user3" class="com.test.User">
        <property name="name" value="王五"></property>
        <property name="age" value="30"></property>
        <property name="address" value="hebei"></property>
        <property name="books">
          <list>
            <ref bean="book"/>
            <ref bean="book2"/>
          </list>
        </property>
      </bean>

       4) 装配 map 属性  (实体类中必须先定义好 map)

      <bean id="user4" class="com.test.User">
        <property name="name" value="王五"></property>
        <property name="age" value="30"></property>
        <property name="address" value="hebei"></property>
        <property name="bookMap">
          <map>
            <entry key="AA" value-ref="book"></entry>
            <entry key="BB" value-ref="book2"></entry>
          </map>
        </property>
      </bean>

      5) 装配 properties 属性

      <bean id="jdbcDatabase" class="com.test.JDBCDatabase">
        <property name="properties">
          <props>
            <prop key="user">root</prop>
            <prop key="password">123</prop>
            <prop key="jdbcUrl">com.mysql.jdbc.Driver</prop>
            <prop key="driverClasss">jdbc:mysql://test</prop>
          </props>
        </property>
      </bean>

      6) 声明集合类型的 bean,  也可以是map

        <util:list id="books2">
          <ref bean="book"/>
          <ref bean="book2"/>
        </util:list>

      7) 简易写法  ref 6) 中的 books2

        <bean id="user5" class="com.test.User" p:name="赵六" p:age="50" p:address="shanghai" p:books-ref="books2"></bean>

      8) 自动装配  byName 是通过 persion中的set方法来匹配装配项, 如下的: address 和 car (在开发中很少会使用)

        <bean id="address" class="com.test2.Address" p:name="北京" p:number="203"></bean>
        <bean id="car" class="com.test2.Car" p:name="宝马" p:price="20000000"></bean>
        <bean id="persion" class="com.test2.Persion" p:name="张三" autowire="byName"></bean>

              byType 是通过类型进行装配(如上的Address类和Car类,  如果有2个同样的类,  就不能装配了)

      9) 配置继承  将相同的去掉,   使用 parent="address2"  来实现继承没有的属性

        <bean id="address2" class="com.test2.Address" p:name="北京" p:number="203"></bean>
        <bean id="address3" p:number="205" parent="address2"></bean>

      10) 抽象 bean ,  只能用来被继承,  不能被实例化、  如果是非抽象bean ,   则必须要有属性值

        <bean id="address2" class="com.test2.Address" p:name="北京" p:number="203" abstract="true"></bean>
        <bean id="address3" p:number="205" parent="address2"></bean>

      11) bean 依赖关系,    如果配置了 depends-on="car"  属性,   则必须要有一个定义了 car  的bean,

      12) bean 的作用域      如果配置了 scope="singleton" 属性,   表示在整个bean的生命周期中是 单例的, 只创建这一个bean  (默认值为这个)

                    如果配置了 scope="prototype" 属性,   表示在整个bean的生命周期中是 原型的, 每次会创建一个新的bean

      13) 通过bean 链接mysql    

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          <property name="user" value="root"></property>
          <property name="password" value="root"></property>
          <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
          <property name="jdbcUrl" value="jdbc:mysql:///mysql"></property>
        </bean>

        ApplicationContext ctx = new ClassPathXmlApplicationContext("jdbcBeans.xml");
        javax.sql.DataSource dataSource = (javax.sql.DataSource)ctx.getBean("dataSource");
        System.out.println(dataSource.getConnection());

      14) 通过引用外部文件来获取 链接数据库信息,  spring 链接数据库

          1> 新建 db.properties 文件, 内容为:      

             user=root
            password=root
            driverClass=com.mysql.jdbc.Driver
            jdbcUrl=jdbc:mysql:///mysql

           2> bean配置文件内容为:    

            <context:property-placeholder location="classpath:db.properties"/>
          3> 配置 bean配置文件内容  类似于 el 表达式的方式来获取
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <property name="user" value="${user}"></property>
              <property name="password" value="${password}"></property>
              <property name="driverClass" value="${driverClass}"></property>
              <property name="jdbcUrl" value="${jdbcUrl}"></property>
            </bean>

      15) 引用外部函数来动态指定属性值 (SpEl表达式)   

        <bean id="car" class="com.properties.Car">
          <property name="name" value="Aodi"></property>
          <property name="price" value="500000"></property>
          <property name="tyrePerimeter" value="#{T(java.lang.Math).PI*50}"></property>
        </bean>

      16) 通过SpEl 表达式来引用其他bean

        <property name="car" value="#{car}"></property>

        通过SpEl 表达式来引用其他bean中的属性 (动态赋值)

        <property name="info" value="#{car.price > 300000 ? '金领' :'白领'}"></property>

      17) bean 的生命周期, init2 和 destroy 都是 Car中自定义的方法,在启动这个IOC容器会先调用 init2 方法,  关闭的时候会调用 destroy 方法

         执行顺序是:  构造方法----> init ----> main ----> destroy

        <bean id="car" class="com.properties.Car" init-method="init2" destroy-method="destroy">
          <property name="name" value="Aodi"></property>
        </bean>

      18) bean 的后置处理器 (检查 bean 的合法性),  这样在这个配置文件下所有的bean都会执行这个后置处理器,  这个配置和在Car类中不需要增加任何东西

        1>  bean 的配置如下:

        <bean class="com.properties.MYBeanPostProcessor"></bean>

        2>  后置处理器类的内容如下: 需要实现 BeanPostProcessor 接口

        public class MYBeanPostProcessor implements BeanPostProcessor {

          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          System.out.println("postProcessBeforeInitialization "+ bean + " "+ beanName);
          return bean;
        }

        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          System.out.println("postProcessAfterInitialization "+ bean + " "+ beanName);
          return bean;
        }

        执行流程将会变为:  构造方法 ----> postProcessBeforeInitialization ----> init ----> postProcessAfterInitialization ---- main      ----> destroy

      19) 静态工厂方法来配置 bean,不需要实例化工厂类,  注意不是配置静态工厂方法实例,而是配置bean实例

        1> bean配置内容如下:class指定静态方法工厂类, factory-method指定指定获取指定bean的具体方法, 

          如果工厂方法需要传入参数, 则使用 constructor-arg 传入参数    

          <bean id="car1" class="com.staticFactory.StaticFactory" factory-method="getCar">
            <constructor-arg value="baoma"></constructor-arg>
          </bean>

        2> 静态方法类内容如下:      

          public class StaticFactory {
            private static Map<String, Car> cars = new HashMap<String, Car>();

            static {
              cars.put("aodi", new Car("aodi",300000));
              cars.put("baoma", new Car("baoma", 500000));
            }

            public static Car getCar(String name) {
              return cars.get(name);
            }
          }

       20) 实例工厂方法: 需要先实例化工厂,  再实例化 bean

        1> bean 代码如下:      

          <bean id="instenceFactory" class="com.staticFactory.InstenceFactory"></bean>

          <bean id="car2" class="com.staticFactory.Car" factory-bean="instenceFactory" factory-method="getCar">
            <constructor-arg value="aodi"></constructor-arg>
          </bean>

        2>  实例工厂代码如下:      

          public class InstenceFactory {
            private Map<String, Car> cars = null;
            public InstenceFactory() {
              cars = new HashMap<String, Car>();
              cars.put("aodi", new Car("aodi", 300000));
              cars.put("ford", new Car("ford", 500000));
            }
            public Car getCar(String name) {
              return cars.get(name);
            }
          }

      21) 通过 spring 自带的 FactoryBean 来配置bean

        1>  bean 配置如下:      

          <bean id="car3" class="com.staticFactory.CarFactoryBean">
            <property name="name" value="BMW"></property>
          </bean>

        2> 自定义类 CarFactoryBean 代码如下:      

          public class CarFactoryBean implements FactoryBean<Car>{
            private String name;
            public void setName(String name) {
              this.name = name;
            }
            public Car getObject() throws Exception {

              return new Car(name, 500000);
            }
            public Class<?> getObjectType() {
              return Car.class;
            }
            public boolean isSingleton() {
              return true;
            }
          }

      22) 通过注解来配置 bean  

        

        1>  扫描annotation包下的所有类和子包下的所有类

          <context:component-scan base-package="com.annotation"></context:component-scan>  

        2>  只扫描 annotation包下的 component包下的所有类

          <context:component-scan base-package="com.annotation" resource-pattern="component/*.class"></context:component-scan>

        3>  不包含 @Repository 来注解 的类      

          <context:component-scan base-package="com.annotation" >
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
          </context:component-scan>

        4>  只包含 @Repository 来注解 的类 (使用 annotation 来对注解类的过滤)       

          <context:component-scan base-package="com.annotation" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
          </context:component-scan>

        5>  不包含具体的类或接口      

          <context:component-scan base-package="com.annotation">
            <context:exclude-filter type="assignable" expression="com.annotation.service.userService.UserService"/>
          </context:component-scan>

        6>  只包含具体的类或接口 (使用 assignable 来指定对具体类来过滤)

          <context:component-scan base-package="com.annotation" use-default-filters="false">
            <context:include-filter type="assignable" expression="com.annotation.service.userService.UserService"/>
          </context:component-scan>

        7>    对 IOC容器中的类里面的属性进行自动装配(也就是说组件之间的相互引用)

          例如:@Autowired,  也可以放到 set方法上, @Autowired默认设置的属性都必须在 IOC 容器里管理,  否则会抛异常 找不到 bean 

              如果容许可以不是 IOC 容器里的bean  可以这样进行设置:@Autowired(required=false)        

            @Controller
            public class UserController {
              @Autowired
              private UserRespository userRespository;

              public void save() {
                System.out.println("UserController...");
              userRespository.save();
              }
            }

         8> @Autowired 可以用在 数组, 集合,  map 上

      

      23)  使用 spring 中的 AOP 来实现 动态代理 前置通知  (顺便看 动态代理实现方式)所需要的包为:

        

        1>  前置通知类  所有通知中可以没有 JoinPoint 参数和其他参数

            1.xml 配置文件    

              <context:component-scan base-package="com.aopImpl"></context:component-scan>

              <!-- 使 AspjectJ 注解起作用: 自动为匹配的类生成 代理对象 -->
              <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

            2. 前置通知类: 其中 @Before("execution(public int com.aopImpl.ArithmeticCalculator.*(int, int))")可以是用通配符来匹配

            比如 @Before("execution(* com.aopImpl.*.*(int, int))") 这样就表示,  第1* 表示任意返回值,com.aopImpl 第2* 表示包下的所

              有类,第3* 表示中的所有方法    

              @Aspect
              @Component
              public class loggingAspect {
                @Before("execution(public int com.aopImpl.ArithmeticCalculator.*(int, int))")  //指定加入的类方法
                public void beforeMethod(JoinPoint joinPoint) {
                  String methodName = joinPoint.getSignature().getName();
                  List<Object> args = Arrays.asList(joinPoint.getArgs());
                  System.out.println("The method "+methodName+" begin with "+args );
                }
               }

           主要有这几种通知

          

          2> 后置通知 (@After)是在方法执行完后或抛出异常时都会执行,   但不能访问方法返回结果,  返回结果需要在返回通知中访问

          3> 返回通知 (@AfterReturning) 是在方法正确执行完之后才执行的, 可以访问到返回值      

            @AfterReturning(value = "execution(* com.aop2.*.*(int, int))", returning="result")
            public void afterReturnAop(JoinPoint joinPoint, Object result) {
              System.out.println("The afterReturning ..."+joinPoint.getSignature().getName()+" result is "+result);
            }

          4> 异常通知, 可以指定具体抛出那个异常才去执行:  比如:  NullPointerException ex     

            @AfterThrowing(value = "execution(* com.aop2.*.*(..))", throwing="ex")
            public void afterThrowingAop(JoinPoint joinPoint, Exception ex) {
              System.out.println("The afterThrowing Exception is : "+ex.getMessage());
            }

          5> 环绕通知,         

            /**
            * 环绕通知需要携带 ProceedingJoinPoint 类型的参数
            * 环绕通知类似于动态代理的全过程, ProceedingJoinPoint 类型的参数可以决定是否执行目标方法
            * 且环绕通知必须有返回值, 返回值即为目标方法的返回值
            * @param pjd
            */
            @Around(value = "execution(* com.aop.*.*(int, int))")
            public void aroundMethod(ProceedingJoinPoint pjd) {
              String methodName = pjd.getSignature().getName();
              try {
                //前置通知
                System.out.println("The method "+methodName+" 前置通知 with "+ Arrays.asList(pjd.getArgs()) );
                //执行目标方法
                Object result = pjd.proceed();
                //返回通知
                System.out.println("The method "+methodName+" 返回通知 with "+ Arrays.asList(pjd.getArgs()) );

              } catch (Throwable e) {
                //异常通知
                System.out.println("The method "+methodName+" 异常通知 with "+ e);
                throw new RuntimeException();
              }
              //后置通知
              System.out.println("The method "+methodName+" 后置通知 with "+ Arrays.asList(pjd.getArgs()) );
            }

          6> 如果有多个切面类,可以使用 @Order(1) 来指定切面优先级,  值越小, 优先级越高, 如:

            @Order(1)
            @Around(value = "execution(* com.aop.*.*(int, int))")
            public void aroundMethod(ProceedingJoinPoint pjd) {

          7> 定义切入点表达式,  以便重用 (该方法不需要填入其他代码)   

            @Pointcut("execution(* com.aop.*.*(int, int))")
            public void jointPointExpression() {}

            使用如下: <1> 同类中  @Before("jointPointExpression()")   

                  <2> 同包不同类中  @Before("类名.jointPointExpression()")  (类名指定义切入点方法的类)

                  <3> 不同包 @Before("包.类名.jointPointExpression()")

          8>  通过xml 来配置通知

            

         

  • 相关阅读:
    9.9递归和动态规划(七)——实现很多图片编辑软件都支持的“填充颜色”功能
    使用azure send grid发送email
    (C++ STL)list的实现
    安卓源代码----安卓系统启动过程(初次研究源代码,表述不当还请见谅)
    Mqtt协议IOS端移植3
    [Servlet&amp;JSP] 标准标签
    table合并单元格
    解决chrome浏览器对于自动填充的input表单添加的默认的淡黄色背景问题 && 一般的浏览器input和button的高度不一致问题
    如何使一个div能够铺满整个页面? && 模态框的制作 && outerHTML
    原生js实现轮播图
  • 原文地址:https://www.cnblogs.com/redhat0019/p/8866721.html
Copyright © 2011-2022 走看看