spring依赖注入

依赖:bean对象的创建依赖于Spring容器
注入:bean对象的属性,由容器注入

spring项目创建流程:

  1. 新建项目,导入依赖(spring-webmvc:包含了所有需要的包)
  2. 编写读取配置文件(xml方式,也可java配置),新建pojo类
    //获取spring的上下文对象,读取配置文件
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
  3. public class Hello {
        private String str;
    
        public void setStr(String str) {
            this.str = str;
        }
    
        public String getStr() {
            return str;
        }
    
        public Hello() {
        }
    
        public Hello(String str) {
            this.str = str;
        }
    
        @Override
        public String toString() {
            return "Hello{" +
                    "str='" + str + '\\'' +
                    '}';
        }
    }
    
  4. 编写配置xml文件,将bean注入容器,将属性注入容器
  5. <!-- 使用spring创建对象,在spring中这些都成为bean
        类型 变量名 = new 类型();
        Hello hello  = new Hello();
        
        class = new 的对象
        id = 变量名
        注意:在这使用property时,bean中必须要有set方法
        name 可以设置这个对象的别名 且可以设置多个别名
        -->
    <!--property中的value指向一个具体的值,还可以ref指向一个对象-->
    <bean id="hello" class="pojo.Hello" name="hello2,hello3 hello4;hello5">
        <property name="str" value="Spring"/>
        <!--构造器注入,index为构造方法的参数下标-->
        <constructor-arg index="0" value="123"/>
    </bean>
    <!--配置别名,取对象的时候可以使用-->
    <alias name="hello" alias="helloAlias"/>
    
  6. 编写测试类
  7. @Test
    public void test(){
        //获取spring的上下文对象,读取配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //使用容器中的bean对象
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
    

非自动装配配置文件详细说明

  1.  <?xml version="1.0" encoding="UTF-8"?>
     <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
            xmlns:c="http://www.springframework.org/schema/c"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
             https://www.springframework.org/schema/beans/spring-beans.xsd">
             <!--项目有不同的人开发,可以写多个配置文件,然后import-->
             <!--如果内容相同,会被合并为一个对象,可以使用多个别名引用-->
             <import resource="bean.xml"/>
             <!--依赖:bean对象的创建依赖于容器
                 注入:bean对象的属性,由容器注入
             -->
             <!--注入,通过set方法注入
             https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies
             -->
             <bean class="pojo.Address" name="address">
                     <property name="addressName" value="浙江工商大学"/>
             </bean>
             <bean class="pojo.Student" name="student">
                     <!--普通注入-->
                     <property name="name" value="牛啊"/>
                     <!--bean对象注入-->
                     <property name="address" ref="address"/>
                     <!--数组注入-->
                     <property name="books">
                             <array>
                                     <value>数据结构</value>
                                     <value>面向对象</value>
                             </array>
                     </property>
                     <property name="hobbies">
                             <list>
                                    <value>听歌</value>
                                     <value>敲代码</value>
                             </list>
                     </property>
                     <property name="cards">
                             <map>
                                     <entry key="学生卡" value="1234"/>
                                     <entry key="地址" value-ref="address"/>
                             </map>
                     </property>
                     <property name="games">
                             <set>
                                     <value>CF</value>
                             </set>
                     </property>
                     <!--null注入-->
                     <property name="wife" >
                             <null/>
                     </property>
                     <!--property注入-->
                     <property name="properties">
                             <props>
                                     <prop key="学号">123456</prop>
                                     <prop key="nn">111</prop>
                             </props>
                     </property>
             </bean>
             <!--p命名标签 通过set方法注入,需要p标签约束
             The p-namespace lets you use the bean element’s attributes
              (instead of nested <property/> elements) to describe your property values collaborating beans, or both.
             -->
             <bean name="teacher" class="pojo.Teacher" p:name="老师"/>
             <!--c标签,必须要有构造器,通过构造器注入,需要c标签约束
             Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1, allows
             inlined attributes for configuring the constructor arguments rather then nested constructor-arg elements.
             -->
             <!--_0是构造方法的第一个参数-->
             <bean class="pojo.Boss" name="boss" c:_0="bossName" c:_1="2"/>
     
             <!--作用域-->
             <!--默认单例模式:即容器中只有一个实例,无论使用多少次,都使用同一个实例-->
             <bean class="pojo.Boss" name="boss1" c:_0="bossName" c:_1="2" scope="singleton"/>
             <!--原型模式:每次从容器中获取的时候,都会新产生一个对象-->
             <bean class="pojo.Boss" name="boss2" c:_0="bossName" c:_1="2" scope="prototype"/> 
     
     </beans>
    
  2. 测试单例属性
  3.  @Test
     public void testStudent(){
         //获取spring的上下文对象,读取配置文件
         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
         //使用容器中的bean对象
         Student student = (Student) context.getBean("student");
         System.out.println(student.toString());
     
         Teacher teacher = (Teacher) context.getBean("teacher");
         System.out.println(teacher.toString());
         //作用域单例模式
         Boss boss = (Boss) context.getBean("boss");
         System.out.println(boss.toString());
         Boss boss1 = (Boss) context.getBean("boss1");
         Boss boss11 = (Boss) context.getBean("boss1");
         System.out.println(boss1 == boss11);
     
         //作用域原型模式
         Boss boss2 = (Boss) context.getBean("boss2");
         Boss boss21 = (Boss) context.getBean("boss2");
         System.out.println(boss2==boss21);
     
     
     }
    

自动装配@AutoWired:在配置bean的时候,如果属性是个对象需要引用另一个对象,不需要在property标签中引用

  1.  <!--自动装配:spring自动寻找bean,自动装配bean到容器--> 
     <bean name="cat" class="pojo.autowired.Cat"/>
     <bean name="dog" class="pojo.autowired.Dog"/> 
     <!--autowire :
     byName:会自动再容器中找和自己对象set方法后面值对应的beanid ,找到这个name对应的bean,这样就不用了再写property属性了
             需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致
     byType: 会自动再容器中找和自己对象属性类型相同的bean ,找到这个name对应的bean,但多个相同bean就会出错。
             需要保证bean的class唯一,并且这个bean需要和对象属性的类型相同
     -->
     <bean name="person" class="pojo.autowired.Person" autowire="byName">
             <property name="name" value="牛啊"/>
     </bean>
    
  2.  @Data//自动创建set get 方法等
     public class Person {
         @Autowired(required = false) //使用required此属性可以为空 
         private Dog dog;
         @Autowired 
         private Cat cat;
         private String name;
     
     }
    

自动装配,使用注解

  1.  
     <?xml version="1.0" encoding="UTF-8"?> 
     <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         https://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         https://www.springframework.org/schema/context/spring-context.xsd">
     <!--使用注解实现自动装配,jdk1.5,spring2.5支持注解-->
     <!--加上这个即可-->
     <context:annotation-config/> 
         <bean id="cat" class="pojo.autowired.Cat"/>
     <bean id="cat1" class="pojo.autowired.Cat"/>
     <bean id="dog" class="pojo.autowired.Dog"/>
     <!--autowire :
         byName:会自动再容器中找和自己对象set方法后面值对应的beanid ,找到这个name对应的bean,这样就不用了再写property属性了
                 需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致
         byType: 会自动再容器中找和自己对象属性类型相同的bean ,找到这个name对应的bean,但多个相同bean就会出错。
                 需要保证bean的class唯一,并且这个bean需要和对象属性的类型相同
         -->
    
         <!-- 在Person类中,Cat和Dog属性上加上@AutoWired 即可
         @AutoWired可以在属性上使用,也可以在set上使用
         使用@AutoWired我们可以不同编写set方法,前提是这个自动装配在IOC(spring)容器中存在,
         且bean的name/id符合名字byName中的Name
         @AutoWired(require = true):此注入属性可以为空,默认为false
    
             **不用@AutoWired可以使用@Resource
         都是实现自动装配
         @AutoWired通过byType的方式实现,必须要有这个对象存在【常用】
         @Resource 默认使用ByName的方式实现,如果找不到名字再用ByType,两个都找不到报错
      -->
     <bean id="person" class="pojo.autowired.Person"/> 
     </beans> 
    
    @Data
    public class Person {
        //@Autowired(required = false) //使用required此属性可以为空
        @Resource(name = "dog")
        private Dog dog;
        @Autowired
        @Qualifier(value = "cat1") //可以指定一个唯一的对象注入
        private Cat cat;
        @Value("nameStr")  //可以注入属性值,复杂属性使用xml较好
        private String name;

自动扫包,注入(注意dtd约束)

  1.  
     <?xml version="1.0" encoding="UTF-8"?>
     
     <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         https://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         https://www.springframework.org/schema/context/spring-context.xsd">
    
         <!--使用自动扫描的包-->
     <context:component-scan base-package="pojo.component"/>
    
         <!--使用注解实现自动装配,jdk1.5,spring2.5支持注解-->
     <!--加上这个即可-->
     <context:annotation-config/>  
     
     </beans>
    
    
  2.  package pojo.component;
     
     import lombok.Data;
     import org.springframework.beans.factory.annotation.Value;
     import org.springframework.stereotype.Component;
     
     /**
      * @Author: nsk
      * @Description:
      * @Date: create in 2021/4/11 14:05
      */
     //Component放到类上,说明这个类被Spring管理了
     @Component
     @Data
     public class User {
         //自动注解属性
         @Value("牛啊")
         private String name;
     }
    
  3. @Nullable 相当于@AutoWired的require属性

  4. @Component 组件,放在类上,说明这个类被Spring管理了,就是bean,衍生注解 在mvc架构分层的时候

  5. dao:使用@Resposutory,和@Component功能相同

  6. service:使用@Service,和@Component功能相同

  7. controller: @Controller ,和@Component功能相同

  8. 四个注解功能一样,都是将谋个类,注册到spring容器中

  9. @Scop(“prototype”):在类名上使用,单例模式,是否每次调用都重新新建对象

java方式依赖注入bean

  1. 编写配置类:
  2. package config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import pojo.component.User;
    
    /**
     * @Author: nsk
     * @Description:
     * @Date: create in 2021/4/11 14:39
     */
    
    /**
     * - @configuration :在配置的类上
     * - @ComponentScan :扫描包
     * - @Import: 导入其他包
     */
    @Configuration //这个也会被Spring容器托管,注册到容器中
    @ComponentScan("pojo.component")
    public class Nconfig {
        //注册一个bean.相当于xml中的bean标签
        //方法的名字相当于bean中的id属性
        //返回值相当于class类型
        @Bean
        public User user(){
            return new User();
        }
    }
    
  3. 使用:
  4. @Test
    public void testJavaConfig(){
        //如果完全使用配置类方式去做,我们就只能通过AnnotationConfig上下文去获取容器,通过配置类的class对象加载!
         ApplicationContext context = new AnnotationConfigApplicationContext(Nconfig.class);
        User user = context.getBean("user",User.class);
        System.out.println(user);
    }