Spring框架技术总结(一),Java自学宝典下载

  • Post author:
  • Post category:java



<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">

    <constructor-arg name="userDao" ref="userDao"></constructor-arg>

</bean>





[](

)2.3.3、依赖注入数据类型

上面的操作,都是注入的引用Bean,都是对UserDao对象的引用进行注入的,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。

对于

集合数据类型

注入:

  • 名称:array,list,set,map,props

  • 类型:

    标签

  • 归属:property标签 或 constructor-arg标签

  • 作用:注入集合数据类型属性

  • 格式:

    
    <property>
    
    	<list></list>
    
    </property>
    
    
    
    

  1. 常量注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        第一种,普通值注入,value-->

</bean>




  1. Bean注入

    • 注意点:这里的值是一个引用,ref

<bean id="student" class="com.kuang.pojo.Student">

<!--        第二种,Bean注入,ref-->

    <property name="address" ref="address" />

</bean>




  1. 数组注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        第三种,数组注入-->

    <property name="books">

        <array>

            <value>红楼梦</value>

            <value>西游记</value>

            <value>水浒传</value>

            <value>三国演义</value>

        </array>

    </property>

</bean>




  1. List注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        第四种,List注入-->

    <property name="hobbys">

        <list>

            <value>听歌</value>

            <value>看木鱼水心</value>

            <value>敲代码</value>

            <value>玩游戏哈哈</value>

        </list>

    </property>

</bean>




  1. Map注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        第五种,Map注入-->

    <property name="card">

        <map>

            <entry key="身份证" value="123456123456123456" />

            <entry key="银行卡" value="654321654321654321" />

        </map>

    </property>

</bean>




  1. set注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        第六种,Set注入-->

    <property name="games">

        <set>

            <value>英雄联盟</value>

            <value>刀塔</value>

            <value>刺客信条</value>

            <value>虐杀原型</value>

        </set>

    </property>

</bean>




  1. null注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        null空值注入-->

    <property name="wife">

        <null />

    </property>

</bean>




  1. Properties注入

<bean id="student" class="com.kuang.pojo.Student">

<!--        properties

    		key = value

-->

    <property name="info">

        <props>

            <prop key="driver">20190525</prop>

            <prop key="url">男</prop>

            <prop key="username">林晓</prop>

            <prop key="password">123456</prop>

        </props>

    </property>

</bean>   





[](

)2.3.3.1、普通数据类型注入


public class UserDaoImpl implements UserDao {

    private String username;

    private int age;



    public void setUsername(String username) {

        this.username = username;

    }



    public void setAge(int age) {

        this.age = age;

    }



    @Override

    public void save() {

        System.out.println(username+"===="+age);

        System.out.println("save running....");

    }

}



  • 在Spring核心配置文件进行配置

    • 普通值的注入,用

      value

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

     <!--        name是属性名,也就是setUsername方法去掉set,之后首字母小写-->

     <!--        name是属性名,也就是setAge方法去掉set,之后首字母小写-->

     <!--        普通值的注入,用value-->

    <property name="username" value="zhangsan"/>

    <property name="age" value="18" />

</bean>





[](

)2.3.3.2、List集合注入

  1. 集合数据类型

    List<String>

    的注入

public class UserDaoImpl implements UserDao {

   privata List<String> strList;

   public void setStrList(List<String> strList){

       this.strList = strList;

   }



    @Override

    public void save() {

        System.out.println("save running....");

    }

}



  • 在Spring核心配置文件进行配置

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

    <!--        name是属性名,也就是setStrList方法去掉set,之后首字母小写-->

    <property name="strList">

        <list>

            <value>aaa</value>

            <value>bbb</value>

            <value>ccc</value>

            <value>ddd</value>

        </list>

    </property>

</bean>



  1. 集合数据类型

    List<User>

    的注入

    • 新建一个实体类User,属性有name、addr,包含getter/setter,有/无参构造,toString方法

public class UserDaoImpl implements UserDao {

   privata List<User> strList;

   public void setUserList(List<User> userList){

       this.userList = userList;

   }



    @Override

    public void save() {

        System.out.println(userList);

        System.out.println("save running....");

    }

}



  • 在Spring核心配置文件进行配置

<bean id="u1" class="com.itheima.domain.User">

    

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

    <!--        name是属性名,也就是setStrList方法去掉set,之后首字母小写-->

    <property name="userList">

        <list>

            <bean class = "com.itheima.domain.User" />

            <ref bean="u1">

        </list>

    </property>

</bean>  





[](

)2.3.3.3、Map集合注入

集合数据类型

Map<String,User>

的注入


public class UserDaoImpl implements UserDao {

   privata Map<String,User> userMap;

   public void setUserMap(Map<String,User> userMap){

       this.userMap = userMap;

   }



    @Override

    public void save() {

        System.out.println(userMap);

        System.out.println("save running....");

    }

}



  • 在Spring核心配置文件进行配置

<bean id="user1" class="com.itheima.domain.User">

    <!--        name是属性名,也就是setNmae方法去掉set,之后首字母小写-->

    <!--        name是属性名,也就是setAddr方法去掉set,之后首字母小写-->

    <property name="name" value="张三">

    <property name="addr" value="西安">    

</bean>

<bean id="user2" class="com.itheima.domain.User">

    <property name="name" value="李四">

    <property name="addr" value="北京">    

</bean> 

        

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

    <!--        name是属性名,也就是setUserMap方法去掉set,之后首字母小写-->

    <property name="userMap">

        <map>

            <!--       这里的key可以随便写,但是后面的value-ref代表bean的引用-->

            <entry key="u1" value-ref="user1">

            <entry key="u2" value-ref="user2">

        </map>

    </property>

</bean> 





[](

)2.3.3.4、Properties注入

集合数据类型

Properties

的注入


public class UserDaoImpl implements UserDao {

   privata Properties properties;

    

   public void setProperties(Properties properties){

       this.properties = properties;

   }



    @Override

    public void save() {

        System.out.println(properties);

        System.out.println("save running....");

    }

}



  • 在Spring核心配置文件进行配置

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

    <!--        name是属性名,也就是setProperties方法去掉set,之后首字母小写-->

    <!--        properties

    			key = value

	-->

    <property name="properties">

        <props>

            <prop key="driver">20190525</prop>

            <prop key="url">男</prop>

            <prop key="username">林晓</prop>

            <prop key="password">123456</prop>

        </props>

    </property>

</bean> 





[](

)2.3.4、使用p命名空间简化配置(了解)

  • 名称:p:propertyName,p:propertyName-ref

  • 类型:

    属性

  • 归属:bean标签

  • 作用:为bean注入属性值

  • 格式:

    
    <bean p:propertyName="propertyValue" p:propertyName-ref="beanId"/>
    
    
    
    
  • 注意:使用p命令空间需要先开启spring对p命令空间的的支持,在beans标签中添加对应空间支持

    
    <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"       xsi:schemaLocation="http://www.springframework.org/schema/beans     https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    
    
    
  • 例子


<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">

    <property name="userDao" ref="userDao" />

    <property name="bookDao" ref="bookDao" />

</bean>





改为:


<bean

   id="userService"

   class="com.itheima.service.impl.UserServiceImpl"

   p:userDao-ref="userDao"

   p:bookDao-ref="bookDao"

/>



[](

)2.4、团队开发


import 一般用于团队开发使用,可以将多个 beans.xml 配置文件,导入合并为一个。

  • 名称:import

  • 类型:

    标签

  • 归属:beans标签

  • 作用:在当前配置文件中导入其他配置文件中的项

  • 格式:

    
    <beans>
    
        <import />
    
    </beans>
    
    
    
    
  • 基本属性:

    
    <import resource=“config.xml"/>
    
    
    
    

​ resource:加载的配置文件名

  • Spring容器加载多个配置文件

    
    new ClassPathXmlApplicationContext("config1.xml","config2.xml");
    
    
    
    
  • Spring容器中的bean定义冲突问题

    • 同id的bean,后定义的覆盖先定义的

    • 导入配置文件可以理解为将导入的配置文件复制粘贴到对应位置

    • 导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同

假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用 import 将所有人的 beans.xml 合并为一个总的!

  • 张三

  • 李四

  • 王五

  • applicationContext.xml


<import resource="{path}/beans.xml"/>

<import resource="{path}/beans1.xml"/>

<import resource="{path}/beans2.xml"/>



[](

)3、Spring配置数据源

===============================================================================

[](

)3.1、数据源的作用


  • 数据源就是连接池

  • 事先实例化数据源,初始化部分连接资源

  • 使用连接资源时从数据源中获取

  • 使用完毕后将连接资源归还给数据源

  • 常见的数据源(连接池):DBCP、C3P0、Druid等

[](

)3.2、数据源开发步骤


  1. 导入数据源的坐标和数据库驱动坐标

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>5.1.47</version>

</dependency>

<dependency>

    <groupId>c3p0</groupId>

    <artifactId>c3p0</artifactId>

    <version>0.9.1.2</version>

</dependency>

<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>druid</artifactId>

    <version>1.1.10</version>

</dependency>

<dependency>

    <groupId>junit</groupId>

    <artifactId>junit</artifactId>

    <version>4.11</version>

</dependency>

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-context</artifactId>

    <version>5.0.5.RELEASE</version>

</dependency>



  1. 在资源resources目录下新建

    jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/test

jdbc.username=root

jdbc.password=root



  1. applicationContext.xml加载jdbc.properties配置文件获得连接信息

    • 首先引入context命名空间和约束路径

    • 命名空间

      
      xmlns:context="http://www.springframework.org/schema/context"
      
      
      
      
    • 约束路径

      
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      
      
      
      

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd

                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">



<!--    加载外部的properties文件-->

    <context:property-placeholder location="classpath:jdbc.properties"/>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="driverClass" value="${jdbc.driver}"/>

        <property name="jdbcUrl" value="${jdbc.url}"/>

        <property name="user" value="${jdbc.username}"/>

        <property name="password" value="${jdbc.password}"/>

    </bean>

</beans>



  1. 测试

@Test

//测试手动创建c3p0数据源(加载properties配置文件)

public void test03() throws Exception {

    //加载类路径下的jdbc.properties

    ResourceBundle rb = ResourceBundle.getBundle("jdbc");

    ComboPooledDataSource dataSource = new ComboPooledDataSource();

    dataSource.setDriverClass(rb.getString("jdbc.drier"));

    dataSource.setJdbcUrl(rb.getString("jdbc.url"));

    dataSource.setUser("jdbc.username");

    dataSource.setPassword("jdbc.password");

    Connection connection = dataSource.getConnection();



}



[](

)3.3、Spring相关API




[](

)3.3.1、applicationContext接口


  • applicationContext

    :接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象



[](

)3.3.2、applicationContext实现类


  • ClassPathXmlApplicationContext

    : 它是从类的根路径下加载配置文件,推荐使用这种


  • FileSystemXmlApplicationContext

    : 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置


  • AnnotationConfigApplicationContext

    : 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解



[](

)3.3.3、getBean()方法


  • getBean("id")

    : 当参数的数据类型是字符串时,表示根据 Bean 的 id 从容器中获得Bean实例,返回是Object,需要强转。


  • getBean(class)

    :当参数的数据类型是Class字节码类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错



[](

)3.3.4、重点API


ApplicationContext app = new ClasspathXmlApplicationContext("xml文件");

app.getBean("id");

app.getBean(class);



[](

)4、Spring注解开发

==============================================================================

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

[](

)4.1、Spring原始注解


Spring原始注解主要是替代Bean的配置

注意:

  • 使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法

<!--指定要扫描的包,这个包下的注解就会生效-->

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



  • 说明

    • 在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描

    • 扫描过程是以文件夹递归迭代的形式进行的

    • 扫描过程仅读取合法的java文件

    • 扫描时仅读取spring可识别的注解

    • 扫描结束后会将可识别的有效注解转化为spring对应的资源加入IoC容器

  • 注意

    • 无论是注解格式还是XML配置格式,最终都是将资源加载到IoC容器中,差别仅仅是数据读取方式不同

    • 从加载效率上来说注解优于XML配置文件

  • 我们也可以开启属性注解支持,这样所有注解都可生效


<!--开启属性注解支持-->

<context: annotation-config/>



| 注解 | 说明 |

| — | — |

| @Component | 使用在类上个用于实例化Bean |

| @Controller | 使用在web层类上用于实例化Bean |

| @Service | 使用在service层类上用于实例化Bean |

| @Repository | 使用在dao层类上用于实例化Bean |

| @Autowired | 使用在字段上上用于根据类型依赖注入 |

| @Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |

| @Resource | 相当于@Autowired + @Qualifier,按照名称进行注入 |

| @Value | 注入普通属性 |

| @Scope | 标注Bean的作用范围 |

| @PostConstruct | 使用在方法上标注方法是Bean的初始化方法 |

| @PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |

[](

)4.2、Bean的定义


我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!

  • 名称:@Component @Controller @Service @Repository

  • 类型:

    类注解

  • 位置:

    类定义上方

  • 作用:设置该类为spring管理的bean

  • 范例:

    
    @Component
    
    public class ClassName{}
    
    
    
    
  • 说明:

    • @Controller、@Service 、@Repository是@Component的衍生注解,功能同@Component
  • 相关属性

    • value(默认):定义bean的访问id

使用

@Component

标识UserDaoImpl需要Spring进行实例化


// 等价于<bean id="userDao" class="com.itheima.Dao.impl.UserDaoImpl"></bean>

@Component("userDao")

public class UserDaoImpl implements UserDao {

    @Override

    public void save() {

        System.out.println("save running...");

    }

}



[](

)4.3、作用域注解


使用

@Scope

标注Bean的范围

  • 名称:

    @Scope

  • 类型:

    类注解

  • 位置:

    类定义上方

  • 作用:设置该类作为bean对应的scope属性

  • 范例:

    
    @Scope
    
    public class ClassName{}
    
    
    
    
  • 相关属性

    • value(默认):定义bean的作用域,默认为singleton

//@Scope("prototype")

@Scope("singleton")

public class UserDaoImpl implements UserDao{

    

}



[](

)4.4、衍生注解



@Component

有几个衍生注解,我们在 web 开发中,会按照mvc三层架构分层!

  • dao层:

    @Repository

  • service层:

    @Service

  • controller层:

    @Controller

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean


@Repository

public class UserDao {

}



@Service

public class UserService {

}


@Controller

public class UserController {

}



```



写上这些注解,就相当于将这个类交给Spring管理装配了!



[](

)4.5、bean的生命周期

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



*   名称:`@PostConstruct`、`@PreDestroy`

    

*   类型:**方法注解**

    

*   位置:**方法定义上方**

    

*   作用:设置该类作为bean对应的生命周期方法

    

*   范例:

    



```

@PostConstruct

public void init() { System.out.println("init..."); }



```



[](

)4.6、加载第三方资源

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



*   名称:`@Bean`

    

*   类型:**方法注解**

    

*   位置:**方法定义上方**

    

*   作用:设置该方法的返回值作为spring管理的bean

    

*   范例:

    

    ```

    @Bean("dataSource")

    public DruidDataSource createDataSource() {    return ……;    }

    

    ```

*   说明:

    

    *   因为第三方bean无法在其源码上进行修改,使用@Bean解决第三方bean的引入问题

        

    *   该注解用于替代XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态

        

    *   @Bean所在的类必须被spring扫描加载,否则该注解无法生效

        

*   相关属性

    

    *   value(默认):定义bean的访问id



[](

)4.7、bean的非引用类型属性注入

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



*   名称:`@Value`

    

*   类型:**属性注解、方法注解**

    

*   位置:**属性定义上方,方法定义上方**

    

*   作用:设置对应属性的值或对方法进行传参

    

*   范例:

    

    ```

    @Value("${jdbc.username}")

    private String username;

    

    ```

*   说明:

    

    *   value值仅支持非引用类型数据,赋值时对方法的所有参数全部赋值

        

    *   value值支持读取properties文件中的属性值,通过类属性将properties中数据传入类中

        

    *   @value注解如果添加在属性上方,可以省略set方法(set方法的目的是为属性赋值)

        

*   相关属性

    

    *   value(默认):定义对应的属性值或参数值



```

@Component("userDao")

public class UserDaoImpl implements UserDao {

    @Value("注入普通数据")

    private String str;

    @Value("${jdbc.driver}")

    private String driver;

    

    @Override

    public void save() {

        System.out.println("save running...");

    }

}



```



[](

)4.8、bean的引用类型属性注入

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



*   名称:`@Autowired`、`@Qualifier`

    

*   类型:**属性注解、方法注解**

    

*   位置:**属性定义上方,方法定义上方**

    

*   作用:设置对应属性的对象或对方法进行引用类型传参

    

*   范例:

    

    ```

    @Autowired(required = false)

    @Qualifier("userDao")

    private UserDao userDao;

    

    ```

*   说明:

    

    *   @Autowired默认按类型装配,指定@Qualifier后可以指定自动装配的bean的id

*   相关属性

    

    *   required:定义该属性是否允许为null



* * *



**自动装配注解感觉视频没有讲解到位,这里引用狂神的案例来进行记录,当然此部分是为了加深理解,也可直接跳过4.6**  

**具体视频讲解:[Bean的自动装配](

)**



* * *



[](

)4.6、Bean的自动装配

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



*   自动装配是Spring满足bean依赖的一种方式

*   Spring 会在上下文中自动寻找,并自动给 bean 装配属性!



在Spring中有三种装配的方式



1.  在xml中显示的配置

2.  在java中显示配置

3.  隐式的自动装配bean【重要】下面主要记录第三种



### [](

)4.6.1、测试环境搭建



1.  新建两个实体类,Cat、Dog 都有一个叫的方法



```

public class Cat {

    public void shout(){

        System.out.println("喵~");

    }

}



public class Dog {

public void shout(){

    System.out.println("汪~");

}

}




2.  新建一个人类,人类含有狗、猫两个变量



public class People {

private Cat cat;

private Dog dog;

private String name;



public Cat getCat() {

    return cat;

}



public void setCat(Cat cat) {

    this.cat = cat;

}



public Dog getDog() {

    return dog;

}



public void setDog(Dog dog) {

    this.dog = dog;

}



public String getName() {

    return name;

}



public void setName(String name) {

    this.name = name;

}



@Override

public String toString() {

    return "People{" +

            "cat=" + cat +

            ", dog=" + dog +

            ", name='" + name + '\'' +

            '}';

}

}




3.  编写Spring核心配置文件



<?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.xsd">



<bean id="cat" class="com.kuang.pojo.Cat" />

<bean id="dog" class="com.kuang.pojo.Dog" />



<bean id="people" class="com.kuang.pojo.People" >

    <property name="name" value="小林子呀~" />

    <property name="cat" ref="cat" />

    <property name="dog" ref="dog" />

</bean>



4.  测试类测试



public class Mytest {

@Test

public void test01(){

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    People people = (People) context.getBean("people");

    people.getDog().shout();//汪~

    people.getCat().shout();//喵~



}

}




### [](

)4.6.2、byName自动装配



*   `autowire="byName"`**(按名称自动装配)**

    

*   由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低,采用自动装配将避免这些错误,并且使配置简单化。

    



1.  修改bean配置,增加一个属性 `autowire="byName"`



<property name="name" value="小林子呀~" />

<property name="cat" ref="cat" />

<property name="dog" ref="dog" />



2.  我们将 cat 的bean id 修改为 catXXX,如下






3.  再次测试,报错



**解释**:



当一个 bean 节点带有 `autowire="byName"`的属性时。



1.  将查找其类中所有的 set 方法名,例如 set Cat,获得将 set 去掉并且首字母小写的字符串,即 cat。

2.  去Spring容器中寻找是否有此字符串名称 id 的对象,例如去找 cat

3.  如果有,就取出注入;如果没有,就报空指针异常



### [](

)4.6.3、byType自动装配



*   `autowire="byType"` (按类型自动装配)

    

*   使用 `autowire="byType"` 首先需要保证:同一类型的对象,在Spring容器中唯一(也就是bean中class属性必须只有一个)。如果不唯一,则报错

    



**测试:**



1.  将people的bean配置修改一下:`autowire="byType"`





版权声明:本文为m0_61452073原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。