<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>
-
常量注入
<bean id="student" class="com.kuang.pojo.Student">
<!-- 第一种,普通值注入,value-->
</bean>
-
Bean注入
- 注意点:这里的值是一个引用,ref
<bean id="student" class="com.kuang.pojo.Student">
<!-- 第二种,Bean注入,ref-->
<property name="address" ref="address" />
</bean>
-
数组注入
<bean id="student" class="com.kuang.pojo.Student">
<!-- 第三种,数组注入-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
</bean>
-
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>
-
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>
-
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>
-
null注入
<bean id="student" class="com.kuang.pojo.Student">
<!-- null空值注入-->
<property name="wife">
<null />
</property>
</bean>
-
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集合注入
-
集合数据类型
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>
-
集合数据类型
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、数据源开发步骤
- 导入数据源的坐标和数据库驱动坐标
<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>
-
在资源resources目录下新建
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
-
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>
- 测试
@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"`