1.什么是Bean?
由Spring IoC容器管理的对象称为Bean.
Spring配置文件支持两种格式,即xml文件格式和properties文件格式。
xml配置文件结构清晰,比properties配置文件更加灵活,但是配置比较繁琐。
Properties配置文件主要是以key-value的形式存在的,只能复制,不能进行其他操作。
属性名称 | 描述 |
---|---|
id | Bean的唯一标识符,IoC容器对Bean的配置都通过该属性完成。id的值必须以字母开始,可以使用字母、数字、下划线等符号 |
name | 表示bean的名称,可以通过name属性为同一个bean同时指定多个名称,每个名称之间用逗号或分号隔开。Spring容器可以通过name属性配置和管理容器中的bean |
class | 指定了Bean的具体实现类,它必须是一个完整的类名,即类的全限定名 |
scope | 表示bean的作用域,属性值可以为singleton(单例)、prototype(原型)、request、session、global Session.默认为singleton |
constructor-arg | < bean >元素的子元素,用于指定对某个bean实例的引用,即< bean >元素中的id或那么属性 |
property | < bean >元素的子元素,用于调用 Bean 实例中的 setter 方法对属性进行赋值,从而完成属性的注入。该元素的 name 属性用于指定 Bean 实例中相应的属性名。 |
ref | < property > 和 < onstructor-arg > 等元素的子元索,用于指定对某个 Bean 实例的引用,即 < bean > 元素中的 id 或 name 属性。 |
value | < property > 和 < constractor-arg > 等元素的子元素,用于直接指定一个常量值 |
list | 用于封装list或数组类型的属性注入 |
set | 用于封装Set类型的属性的注入 |
map | 用于封装Map类型的属性的注入 |
entry | < map > 元素的子元素,用于设置一个键值对。其 key 属性指定字符串类型的键值,ref 或 value 子元素指定其值 |
init-method | 容器加载 Bean 时调用该方法,类似于 Servlet 中的 init() 方法 |
destory-method | 容器删除 Bean 时调用该方法,类似于 Servlet 中的 destroy() 方法。该方法只在 scope=singleton 时有效 |
lazy-init | 懒加载,值为 true,容器在首次请求时才会创建 Bean 实例;值为 false,容器在启动时创建 Bean 实例。该方法只在 scope=singleton 时有效 |
<!--加载外部的配置文件-->
<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>
<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>
<!--配置JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置RoleService-->
<bean id="roleService" class="itheima.service.impl.RoleServiceImpl">
<!-- ref 引用的是下面配置RoleDao中的id名称-->
<property name="roleDao" ref="roleDao"/>
</bean>
<!--配置RoleDao-->
<bean id="roleDao" class="itheima.dao.impl.RoleDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
2.什么是Bean属性注入?
bean属性注入,简单的说就是将属性注入到Bean中的过程,这属性可以是普通属性,也可以是一个对象(bean).
Spring有两种方式实现属性注入:
(1)构造函数注入
(2)setter注入(设值注入)
构造函数注入:
大致步骤如下:
(1)在bean中添加一个有参构造函数,构造函数内的每一个参数代表一个需要注入的属性
(2)在Spring的xml配置文件中,通过< bean>对bean 进行定义
(3)使用constructor-arg元素对构造函数内的属性进行赋值
public class User {
private Long id;
private String username;
private String email;
private String password;
private String phoneNum;
public User(Long id, String username, String email, String password, String phoneNum) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.phoneNum = phoneNum;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
", phoneNum='" + phoneNum + '\'' +
'}';
}
}
}
<!--使用构造函数注入属性-->
<bean id="user" class="itheima.domain.User">
<constructor-arg name="id" value="3"></constructor-arg>
<constructor-arg name="email" value="2090877902@qq.com"></constructor-arg>
<constructor-arg name="password" value="1234567"></constructor-arg>
<constructor-arg name="phoneNum" value="18790875693"></constructor-arg>
<constructor-arg name="username" value="zhangsan"></constructor-arg>
</bean>
public class test {
public static void main(String[] args) {
//获得ApplicationContext容器
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//获得容器中创建管理的user对象
User user=context.getBean("user",User.class);
System.out.println(user);
}
}
setter注入:
通过bean的setter方法,将属性值注入到bean的属性中。
在Spring实例化Bean的过程中,IoC容器首先会调用默认的构造方法(无参构造)实例化Bean对象(Java对象),然后通过Java的反射机制调用这个Bean的setXxx()方法,将属性值注入到Bean中。
大致步骤如下:
(1)在bean中提供一个默认的无参构造函数,并为所有需要注入的属性提供一个setXxx方法。
(2)在spring的xml配置文件中,使用< bean>对bean进行定义。
(3)在< bean>元素内使用< property>元素对各个属性进行赋值。
public class User {
private Long id;
private String username;
private String email;
private String password;
private String phoneNum;
//创建一个无参构造函数
public User(){
}
public User(Long id, String username, String email, String password, String phoneNum) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.phoneNum = phoneNum;
}
public void setId(Long id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
", phoneNum='" + phoneNum + '\'' +
'}';
}
}
<!--使用setter方法注入属性-->
<bean id="user" class="itheima.domain.User">
<property name="id" value="4"/>
<property name="password" value="123121"/>
<property name="username" value="lisi"/>
<property name="email" value="20989017@qq.com"/>
<property name="phoneNum" value="18909876701"/>
</bean>
public class test {
public static void main(String[] args) {
//获得ApplicationContext容器
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//获得容器中创建管理的user对象
User user=context.getBean("user",User.class);
System.out.println(user);
}
}
短命名空间注入:
p命名空间 | 是setter方式属性注入的一种快捷实现方式 |
---|---|
c命名空间 | 是构造函数属性注入的一种快捷实现方式 |
p命名空间:
(setter方式注入)
<bean id="Bean 唯一标志符" class="包名+类名" p:普通属性="普通属性值" p:对象属性-ref="对象的引用">
要提供无参构造函数!!!
public class User {
private Long id;
private String username;
private String email;
private String password;
private String phoneNum;
private Role role;
//不写构造参数时会默认提供无参构造
public void setRole(Role role) {
this.role = role;
}
public void setId(Long id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", role=" + role +
'}';
}
}
public class Role {
private Long id;
private String roleName;
private String roleDesc;
public void setId(Long id) {
this.id = id;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName
'}';
}
}
添加: xmlns:p=“http://www.springframework.org/schema/p”
<!--短命名空间注入-->
<bean id="user" class="itheima.domain.User" p:username="张三" p:role-ref="role" p:id="5"/>
<bean id="role" class="itheima.domain.Role" p:id="1" p:roleName="学生"/>
public class test {
public static void main(String[] args) {
//获得ApplicationContext容器
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//获得容器中创建管理的user对象
User user=context.getBean("user",User.class);
System.out.println(user);
}
}
c命名空间:
(构造函数属性注入)
<bean id="Bean 唯一标志符" class="包名+类名" c:普通属性="普通属性值" c:对象属性-ref="对象的引用">
同p命名空间写法(不同的是它要提供有参构造函数!!!)
注解形式:
- 常用的声明创建对象的注解
- 标注在类上
- @Component
用于实例化对象,相当于配置文件中的< bean id=“” class=“”/>
它支持一个属性value,相当于xml中bean的id。如果不写,默认值为类名的首字母小写 - @Controller @Service @Repository
这三个注解的功能跟@Component完全一样,只不过他们三个比较有语义化。
@Controller
一般标注在表现层的类上
@Service
一般标注在业务层的类上
@Repository
一般标注在持久层的类上
推荐使用这三个,当一个类实在不好归属在这三个层上时,再使用@Component
- 对象的依赖注入的注解
- 可以标注在类上,方法上,属性上。常用的是标记在属性上
@Autowired
标注在属性上:
@Autowired
private UserService userService
这个是用来到IoC容器中需要相对于的bean对象。
找到的话,就会进行依赖注入,就是给元素赋值。