代码地址: https://github.com/Zhuyaqiang/spring-study
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.4.RELEASEversion>
dependency>
原业务中, 用户的需求可能会影响原来的代码, 需要根据用户的需求去修改原代码
使用Set接口实现, 发生了革命性的变化
private UserDao userDao;
// 利用set动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
从本质上解决了问题, 程序员不用管理对象的创建, 系统的耦合性大大降低, 可以专注业务实现. 是IoC的原型
默认使用无参构造创建对象
使用有参构造创建独享
下标赋值
<bean id="user" class="com.zyq.pojo.User">
<constructor-arg index="0" value="zyq">constructor-arg>
bean>
类型赋值(不建议使用)
<bean id="user" class="com.zyq.pojo.User">
<constructor-arg type="java.lang.String" value="zzz">constructor-arg>
bean>
参数名赋值
<bean id="user" class="com.zyq.pojo.User">
<constructor-arg name="name" value="yqq">constructor-arg>
bean>
总结: 配置文件加载的时候, 容器中管理的对象就已经初始化了, 且只有一份
<alias name="user" alias="dfsfdsfsd">alias>
<bean id="userT" class="com.zyq.pojo.UserT" name="user2 u2, u3; u4">
<property name="name" value="啦啦啦">property>
bean>
一般用于团队开发使用, 可以将多个配置文件, 导入合并为一个
假设项目中有多人开发, 负责不同的类开发, 不同的类需要注册在不同的bean中, 可以利用import将所有人的beans.xml合并为一个总的配置文件
<import resource="beans.xml">import>
<import resource="beans2.xml">import>
【环境搭建】
对应spring-04-di
复杂类型
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
真实测试环境
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String, String> card;
private Set<String> games;
private Properties info;
private String wife;
}
beans.xml
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.zyq.pojo.Student">
<property name="name" value="zyq">property>
bean>
beans>
测试类
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getAddress());
}
}
可以使用p命名空间和c命名空间进行注入
<bean id="user" class="com.zyq.pojo.User" p:name="zyq" p:age="18">bean>
<bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq">bean>
注意点: p命名和c命名空间, 需要导入xml约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
单例模式(Spring默认机制):
<bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq" scope="singleton">bean>
原型模式: 每次从容器中get的时候, 都会产生一个新对象
<bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq" scope="prototype">bean>
其余的和request, session, application. 只能在web开发中使用到
在Spring中有三种装配方式
对应spring-05-Autowired
<bean id="people" class="com.zyq.pojo.People" autowire="byName">
<property name="name" value="zyq">property>
bean>
和ByName类似, 会自动在容器上下文中查找, 和自己对象属性类型相同的bean, 必须保证类型全局唯一
小结:
使用注解须知:
导入约束, context约束
配置注解的支持,
(重要)**
<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:annotation-config/>
beans>
@Autowired可以直接在属性上使用, 也可以在set方法上使用
Autowired使用反射机制, 因此可以不用编写set方法, 前提是自动装配的属性在IoC(Spring)容器中存在, 且符合名字byName
补充:
1. `@Nullable`字段标注了这个注解说明这个字段可以为null
@Autowired(required = false)
默认为true, 如果显式定义了属性为false, 说明这个对象可以为null 否则不允许为null@Autowired
完成的时候, 可以使用@Qualifier(value="xxx")
来指定@Resource注解也有自动装配的功能
@Resource
和@Autowired
的异同:
@Autowired
默认通过byType方式实现, 而且必须要求这个对象存在@Resource
默认通过byName的方式实现, 如果找不到名字, 则通过byType实现, 如果两个方式都找不到就报错在Spring4之后, 要使用注解开发, 必须要保证aop的包导入了
@Component
放在类上说明类被Spring管理了
@Component
public class User {
public String name;
@Value("zzz")
public void setName(String name) {
this.name = name
}
}
@Component
有几个衍生注解, 在web开发中, 会按照mvc三层架构分层
@Repository
@Service
@Controller
功能都代表将某个类注册到Spring容器中, 装配Bean
- @AutoWired: 通过类型自动装配. 如果Autowired不能通过名字唯一自动装配上属性, 则需要通过@Qualifier(value="xxx")
- @Nullable: 字段标记了这个注解说明这个字段可以为null
- @Resource: 通过名字, 类型自动装配
@Scope("prototype")
xml与注解
xml与注解最佳实践:
xml用来管理bean
注解用来进行属性注入
使用过程中, 只需要注意一个问题: 想让注解生效, 就要开启注解支持
<context:component-scan base-package="com.zyq.pojo">context:component-scan>
<context:annotation-config>context:annotation-config>
完全不使用Spring的xml配置
实体类:
@Component
public class User {
// 属性注入值
@Value("zyq")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
配置文件类:
@Configuration // 也会被Spring容器托管, 注册到容器中, 因为这个注解本来就是一个@Component, @Configuration代表这是一个配置类, 相当于beans.xml
@ComponentScan("com.zyq.pojo")
@Import(MyConfig2.class)
public class MyConfig {
// 注册一个bean, 相当于配置文件xml中的bean标签
// 方法名相当于bean标签中的id属性
// 方法的返回值, 相当于bean标签中的class属性
@Bean
public User getUser() {
return new User(); // 就是返回要注入到bean的对象
}
}
测试类:
public class MyTest {
public static void main(String[] args) {
// 如果完全使用类配置类方式, 就只能通过AnnotationConfig上下文来获取容器, 通过配置类的class对象加载
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getUser");
System.out.println(user.getName());
}
}
纯Java的配置方式, 在SpringBoot中随处可见