zoukankan      html  css  js  c++  java
  • Spring-IOC

    赋值方式

    构造器赋值

    无参构造器:(利用set方法赋值)

    <bean id="p1" class="com.zh.pojo.Person">
        <property name="name" value="zh"/>
        <property name="age" value="33"/>
        <property name="sex">
        <value>男</value>
        </property>
    </bean>
    

    有参构造器:

    属性名称赋值:
    <bean id="p2" class="com.zh.pojo.Person">
         <constructor-arg name="age" value="2"/>
         <constructor-arg name="sex" value="e"/>
         <constructor-arg name="name" value="zh"/>
    </bean>
    
    省略name赋值:
    <bean id="p3" class="com.zh.pojo.Person">
         <constructor-arg value="2"/>
         <constructor-arg value="e"/>
         <constructor-arg value="zh"/>
    </bean>
    
    属性索引赋值:
    <bean id="p3" class="com.zh.pojo.Person">
        <constructor-arg index="0" value="你好"/>
            <!--重载情况下,type可以指定参数类型
            Person(String name, String sex, String email)
            Person(String name, Integer age,String sex)
            -->
        <constructor-arg index="1" type="java.lang.Integer" value="23"/>
         <constructor-arg index="2" value="ec"/>
    </bean>
    

    p命名空间赋值(set方法赋值):

    1.配置文件中导入p命名空间
    xmlns:p="http://www.springframework.org/schema/p"
    2.使用
    <bean id="person04" class="com.zh.pojo.Person" p:age="12" p:sex="男" p:name="zh"/>
    

    c命名空间赋值(构造方法赋值):

    1.配置文件中导入c命名空间:
    xmlns:c="http://www.springframework.org/schema/c"
    2.使用
    <bean id="person05" class="com.zh.pojo.Person"c:age="13" c:sex="nv" c:name="zhs" c:email="33@qq.com"/>
    

    不同类型属性的赋值:

    基本类型直接使用
    
    <property></property>赋值
    
    复杂类型使用标签体
    

    nul值:

    <property name="lastName">
        <!--    使用null值(默认不赋值同为null)-->
        <null></null>
    </property>
    

    引用类型赋值:

    方式一:引用外部bean(地址引用)
    <bean id="car1" class="com.zh.pojo.Car">
            <property name="carName" value="宝马"/>
            <property name="color" value="blue"/>
            <property name="price" value="4600"/>
    </bean>
    <bean id="p1" class="com.zh.pojo.Person">
         <property name="car" ref="car1">
    </bean>
    
    方式二:引用内部bean
    <bean id="p1" class="com.zh.pojo.Person">
         <property name="car">
         	<bean class="com.zh.pojo.Car">
          		<property name="carName" value="宝马"/>
          		<property name="color" value="blueS"/>
          		<property name="price" value="100000"/>
          	</bean>
    </bean>
    

    List赋值:

    <property name="books">
     <!--books=new ArrayList<Book>()-->
        <list>
        	 <bean id="book2" class="com.zh.pojo.Book" p:bookName="西游记" p:author="吴承恩"></bean>
         <!-- 引用外部bean-->
              <ref bean="book1"/>
        </list>
    </property>
    

    map赋值:

    <property name="maps">
    	<!--maps=new HashMap()-->
        <map>
            <!--每个entry代表一个键值对-->
           <entry key="key01" value="zh"></entry>
           <entry key="key02" value="12"></entry>
           <entry key="key03" value-ref="book1"></entry>
           <entry key="key04">
           		<bean class="com.zh.pojo.Car">
               		<properties name="carName" value="法拉利">					</properties>
               </bean>
           </entry>         <
        </map>
    </property>
    

    Properties赋值:

    <property name="properties">
        <!--properties=new Properties(),k、v都是String-->
        <props>
        	<prop key="userName">root</prop>
            <prop key="passWord">zh1234</prop>
            <prop key="link">www.person.top</prop>
        </props>
    </property>
    

    util命名空间:

    <!--util命名空间创建集合类型的bean 全局可复用-->
    <util:map>
     	<entry key="key01" value="q"/>
      	<entry key="key02" value="w"/>
        <entry key="key03" value-ref="book1"/>
        <entry key="key04">
            <bean class="com.zh.pojo.Car">
                <property name="carName">
                     <value>玛莎拉蒂</value>
                 </property>
             </bean>
         </entry>
    </util:map>
    <util:list id="list1">
       <bean id="book2" class="com.zh.pojo.Book" p:bookName="西游记" p:author="吴承恩"></bean>
         <ref bean="book1"/>
     </util:list>
    
    <bean id="p2" class="com.zh.pojo.Person">
        <property name="maps" ref="map1"/>
        <property name="books" ref="list1"/>
    </bean>
    

    bean之间的依赖(改变创建顺序)

    <!--depends-on可以改变默认创建顺序-->
    <bean id="car" class="com.zh.pojo.Car" depends-on="p1,b1"/><bean id="p1" class="com.zh.pojo.Person"/>
    <bean id="b1" class="com.zh.poj.Book"/>
    

    bean的作用域(单实例与多实例)

     scope="singleton" 单实例(默认),容器启动完成之前创建,任何时候获取的都是同一个对象
     scope="prototype" 多实例,在容器中获取时创建,每次获取时都会创建一个新的对象
    <bean id="p1" class="com.zh.pojo.Person" scope="singleton"/>
    <bean id="p1" class="com.zh.pojo.Person" scope="prototype">
    

    工厂模式创建bean:

    bean的创建默认就是框架利用反射new出来的实例
    工厂模式:工厂帮我们创建对象,专门帮我们创建对象的类就是工厂
    

    pojo

    package com.zh.pojo;
    
    public class AirPlane {
    private String fdj;
    private String length;
    private String personNum;
    private String jzName;
    private String fjsName;
    }
    

    静态工厂创建:

    (不需要创建工厂本身,通过类名.静态方法直接调用)

    AirplaneStaticFactory:

    package com.zh.Factory;
    
    import com.zh.pojo.AirPlane;
    @Data
    @NoArgsConstructo
    @AllArgsConstructor
    public class AirplaneStaticFactory {
    
        private static AirPlane getAirplane(String jzName){
            System.out.println("静态工厂创建");
            AirPlane airPlane = new AirPlane();
            airPlane.setFdj("天行");
            airPlane.setFjsName("zhs");
            airPlane.setJzName(jzName);
            airPlane.setLength("12.3m");
            airPlane.setPersonNum("8909090");
            return airPlane;
        }
    
    }
    

    在容器中注册

    <!--
    	class:静态工厂全类名
    	factory-method:指定工厂方法
    	constructor-arg:给方法传参
    -->
    <bean id="airPlane1" class="com.zh.Factory.AirplaneStaticFactory" factory-method="getAirplane">
    <constructor-arg value="001"></constructor-arg>
    </bean>
    

    实例工厂:

    1. 先配置出实例工厂对象
    2. 配置我们要创建的对象使用哪个工厂创建

    AirplaneInstanceFactory:

    package com.zh.Factory;
    
    import com.zh.pojo.AirPlane;
    
    public class AirplaneInstanceFactory {
    
        private AirPlane getAirplane(String jzName){
            System.out.println("实例工厂创建");
            AirPlane airPlane = new AirPlane("22","ff","2f",jzName,"zhs");
            return airPlane;
        }
    }
    

    在容器中注册:

    <bean id="instanceFactory" class="com.zh.Factory.AirplaneInstanceFactory"/>
    <!--
    	factory-bean:指定哪个工厂实例
    	factory-method:指定使用工厂实例中的哪个方法
    -->
    <bean id="airPlane2" class="com.zh.pojoj.AirPlane" factory-bean="instanceFactory" factory-method="getAirplane">
    	<consturctor-arg value="002"></consturctor-arg>
    </bean>
    

    FactoryBean(Spring中规定的一个接口)

    只要这个接口的实现类,Spring都认为是一个工厂
    
    1.ioc容器启动的时候不会创建实例
    
    2.FactoryBean:容器中获取时才会创建对象
    

    MyFactoryBeanImplement

    /**
     * 实现了FactoryBean接口的类是Spring可以认识的工厂类
     * Spring会自动的调用工厂方法创建实例
     * 1.编写一个FactoryBean的实现类
     * 2.在spring配置文件中 进行注册
     */
    public class MyFactoryBeanImplement implements FactoryBean<AirPlane> {
        public MyFactoryBeanImplement() {
            super();
        }
    
        /**
         * getObject:工厂方法,返回创建的对象
         */
        public AirPlane getObject() throws Exception {
            System.out.println("FactoryBean创建对象");
            AirPlane airPlane = new AirPlane("22", "ff", "2f", UUID.randomUUID().toString(), "zhs");
            return airPlane;
        }
    
        /**
         * 返回创建的对象类型
         * spring会自动调用这个方法来确认创建的对象类型
         *
         */
        public Class<?> getObjectType() {
    //        System.out.println("FactoryBean创建对象2");
    
    //        return AirPlane.class;
            return null;
        }
    
        /**
         * 创建的对象是否为单例
         *
         * @return
         */
        public boolean isSingleton() {
    //        System.out.println("FactoryBean创建对象3");
    
            return true;
        }
    
    }
    

    在容器中注册:

    <bean id="myFactoryBean" class="com.zh.Factory.MyFactoryBeanImplement"/>
    

    创建带有生命周期的bean:

    bean的生命周期:bean的创建到销毁
    	ioc容器中注册的bean:
    		1).单实例bean,容器启动的时候创建完成,容器关闭时销毁
    		2).多实例bean,获取的时候才会创建
    我们可以为bean自定义一些生命周期方法,Spring在创建或销毁时就会调用指定方法
     	单实例:bean的生命周期
     		(容器启动)构造器====>初始化方法====>(容器关闭)销毁方法
     	多实例:获取bean(构造器====>初始化方法=====>容器关闭不会调用bean的销毁方法)
     	后置处理器:
     		(容器启动)构造器=====>后置处理器before====>初始化方法=====>后置处理器after=======>bean初始化完成
    

    自定义生命周期方法:

    Book.java

    public void destory() {
        System.out.println("销毁了");
    }
    
    public void init() {
        System.out.println("初始化");
    }
    

    使用:

    <bean id="book1" class="com.zh.pojo.Book" destroy-method="destory" init-method="init">
    

    后置处理器(可在bean初始化前后调用方法)

    1.实现接口

    public class MyBeanPostProcessor implements BeanPostProcessor {
        
        //    初始化之前调用
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + "bean将要调用初始化方法l......BeforeInitialization");
            return bean;
        }
    
        /*
        初始化完成之后调用
         */
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + "bean初始化方法调用完了.....AfterInitialization");
            return bean;
        }
    }
    

    2.在容器中注册

    <bean id="MyBeanPostProcessor" class="com.zh.pojo.MyBeanPostProcessor">
    </bean>
    <!--无论bean是否有初始化方法,后置处理器都会默认其有-->
    <bean id="car" class="com.zh.pojo.Car"></bean>
    

    Spring管理连接池

    将数据库连接池作为单实例是最好的,一个项目就是一个连接池,
     连接池里管理很多连接,连接是直接从连接池中拿
    可以让Spring帮我们创建连接池对象,(管理连接池)
    

    db.properties:

    user=root
    pwd=zh123456
    url=jdbc:mysql://localhost:3306/mybatis
    driver=com.mysql.cj.jdbc.Driver
    

    容器中注册数据源组件:

    <!--
    加载外部配置文件(依赖context命名空间)  固定写法classpath:表示引用类路径下的一个资源
    -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${user}"/>
        <property name="password" value= "${pwd}"/>
        <property name="jdbcUrl" value="${url}"/>
        <property name="driverClass" value="${driver}"/>
     </bean>
    

    Test

     @Test
       public void TestConnectPool() throws SQLException {
          ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config4.xml");
    //     根据类型获取组件时,可以获取到这个类型下的所有实现类子类等等
          DataSource dataSource = context.getBean(DataSource.class);
          Connection connection = dataSource.getConnection();
          System.out.println(connection);
          }
    

    基于xml的自动装配(自动赋值):

    自动装配只用于自定义类型的属性
    byName和byType都是使用set方法赋值
    constructor:使用构造方法赋值
    
    1. autowire:default/no(不自动装配)

    2. autowire:byName:按照名字

       		private Car  car:在容器中查找以属性名为id的组件并赋值,找不到就为null
      
    3. autwire:byType:在容器中查找与属性有且只有一个同类型的组件,找不到就为null

    4. autowire:constructor:

      ​ public Person(Car car)

      ​ 按照构造方法赋值:

      ​ 1.先按照有参构造器参数的类型进行装配,没有就为null

      ​ 2.如果按照类型找到了多个,在根据byName进行查找,找到就装配,找不到就null

    通过注解配置组件:

    通过注解,可以快速的将这个组件添加到ioc容器中
    @Controller:控制器,建议控制器层(controller包下)组件使用
    @Service:业务逻辑,建议service包下组件使用
    @Repository:dao层下组件使用
    @Component:给其他组件使用
    (四个注解都可以使用,为了便于维护,建议分类使用)
    使用注解将组件快速添加到容器步骤:
    1.给要添加的组件上添加注解(四个中任何一个)
    2.配置自动包扫描,自动扫描添加了注解的组件(依赖context命名空间)
    3.一定要导入aop包(idea自动导入context下要使用的包)
    
     使用注解加入到容器中的组件,和使用配置加入到容器中的组件行为是一样的
      1.组件的id.默认就是组件的列名首字母小写
      @Service("bookServiceZh")
      2.组件的作用域,默认就是单例的
      @Scope(value = "prototype")
    

    context:exclude-filter:指定包扫描是不包含的类

     *type=“annotation”:指定排除规则,排除使用了指定注解的组件
          expression=“注解全类名“
     *type="assignable":指定排除某个具体的类,按照类排除
          expression=“类的全类名”
    【aspectj(aspectj表达式)、custom(自定义一个TypeFilter,自己写代码决定哪些使用)、regex(正则表达式)】
    
    <context:component-scan base-package="com.zh" use-default-filters="false">
        <context:exclude-filter type="assignable" expression="com.zh.dao.BookDao"/>
    </context:component-scan>
    

    context:include-filter:指定包扫描只包含的类

    包扫描时,默认将有注解的组件全部扫描进来
    user-default-filters:禁用默认规则,只保留哪些
    
    <context:component-scan base-package="com.zh" use-default-filters="false">
        <context:include-filter type="assignable" expression="com.zh.dao.BookDao"/>
    </context:component-scan>
    

    @AutoWired自动装配

    @AutoWired原理:
    	@AutoWired
    	private BookService bookService;
    	1.先按照类型去容器中找到相应的组件;bookService=ioc.getBean(BookService.class)
    	2.没找到,报错
    	3.找到多个
    		按照变量名作为id继续匹配,BookService,BookServiceExt
            如果找不到报错,可以使用@Qualifier指定id名(在自动装配找到同类型多个时,默认以属性为id继续查找)
        @AutoWired标注的自动装配的属性默认是一定要装配的
        @AutoWired(require=false)指定属性不能自动装配时,为null
    

    @AutoWired、@Resource区别:

    @AutoWired、@Resource、@Inject:都可以用于自动装配,区别:
    @AutoWired:最强大,只能用于Spring容器
    @Resource:java标准,扩展性更强,也适用于其他容器框架(EJB)
    @Inject:EJB
    
    执行顺序不同:@Autowired默认通过bytype的方式实现。而且必须要有这个对象
     @Resource默认通过byname的方式实现
    

    方法上使用@AutoWired

     /**
      * 方法上使用@AutoWired:
      * 1)这个方法会在bean创建时自动运行
      * 2)这个方法上的每个参数都会自动注入值(引用类型)
      */
        @Autowired
    //    @Resource
        public void doGet2(@Qualifier("bookServiceExt") BookService bookService, BookDao bookDao){
            System.out.println("spring启动了这个方法"+bookService+"===>"+bookDao);
        }
    

    泛型依赖注入:

    image-20210210000114403

    Spring表达式(Spring Expression Language)

    在SpEl中使用字面量、
    引用其他bean、
    引用其他bean的某个属性值、
    调用非静态方法、
    调用静态方法、
    使用运算符
    
    <bean id="p2" class="com.zh.pojo.Person">
        <!--字面量:#{}-->
        <property name="salary" value="#{12*43}"/>
    <!--    引用其他bean的某个属性值-->
    <property name="lastName" value="#{car1.carName}"/>
    <!--    引用其他bean-->
    <property name="car" value="#{car1}"/>
    <!--    调用静态方法:#{T(全类名).静态方法名()}-->
        <property name="email" value="#{T(java.util.UUID).randomUUID().toString()}"/>
        <!--调用非静态方法:对象.方法名-->
        <property name="gender" value="#{car1.getCarName()}"/>
     </bean>
    
  • 相关阅读:
    史上最全HashMap红黑树解析
    使用httpClient 调用get,Post接口
    VS 安装resharper 后 无法进行UnitTest
    [转]大数据的高并发的数据库优化
    【转】2019年7月份,阿里最新Java高频面试真题汇总
    【转】Apache的架构师们遵循的30条设计原则
    B树索引最通俗易懂的介绍
    spring Boot 学习(八、Spring Boot与与监控管理)
    spring Boot 学习(七、Spring Boot与开发热部署)
    vs快捷键
  • 原文地址:https://www.cnblogs.com/zh93/p/14703907.html
Copyright © 2011-2022 走看看