第一阶段:
IOC Bean创建对象的三种方式:
1. 无参构造器创建对象,默认。
(1). 基本类型:value
<bean id="hello" class="com.edward.pojo.Hello">
<property name="str" value="SpringStudy"></property>
</bean>
(2). 引用类型:ref
<bean id="cat" class="com.edward.pojo.Cat"></bean>
<bean id="student" class="com.edward.pojo.Student">
<property name="cat" ref="cat"></property>
</bean>
2. 有参构造器创建对象,有以下3种:
<!-- 第一种,下标赋值 -->
<bean id="user" class="com.edward.pojo.User">
<constructor-arg index="0" value="牧羊狼的狼">
</bean>
<!-- 第二种,通过类型创建,不建议使用!! -->
<bean id="user" class="com.edward.pojo.User">
<constructor-arg type="java.lang.String" value="牧羊狼的狼">
</bean>
<!-- 第三种,直接通过参数名设置 -->
<bean id="user" class="com.edward.pojo.User">
<constructor-arg name="name" value="牧羊狼的狼">
</bean>
3. 命名空间的方式注入:
<?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/chema/p"
xmlns:c="http://www.springframework.org/chema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p命名空间注入,可以直接注入属性的值:property -->
<bean id="user" class="com.edward.pojo.User" p:name="牧羊狼" p:age="18">
<!-- c命名空间注入,可以直接注入属性的值:constructor-args -->
<!-- User类中要有构造器 -->
<bean id="user" class="com.edward.pojo.User" c:name="牧羊狼" c:age="18">
第二阶段:
之前:需要<property>的 ref 引入实例化的对象
进化:直接用 autowire 属性自动引入
(1). byName: 会在容器上下文中查找,和自己对象set方法后面的值对应的beanid
<bean id="cat1" class="com.edward.pojo.Cat"></bean>
<bean id="student" class="com.edward.pojo.Student" autowire="byName">
</bean>
Student.java:
(2). byType: 会在容器上下文中查找,和自己对象属性类型相同的bean
如下:name="cat",自己对象属性类型为cat,正好有class="xxxCat"的<bean>
<bean id="cat" class="com.edward.pojo.Cat"></bean>
<bean id="student" class="com.edward.pojo.Student" autowire="byType">
<!-- <property name="cat" ref="cat"></property> -->
</bean>
MyTest.java:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = context.getBean("student", Student.class);
student.getCat().shout();
}
}
byType时, 被引用的bean的id可以不写,但是class必须全局唯一 !!!!!
成功:
失败:
第三阶段 : 注解自动装配
之前:在xml 文件中,autowire 属性注入引用类型
进化:在 Class 文件中,@Autowired @Qualifier @Resource 注解注入
@Autowired:通过 byType 的方式注入
第一步:导入约束链接,添加 <context:annotation-config /> 配置;
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config />
<bean id="school2" class="com.edward.pojo.School"></bean>
<bean id="hello" class="com.edward.pojo.Hello"></bean>
</beans>
第二步:给Class文件中的对象属性添加 @Autowired注解 (也可以在set方法上使用);
setSchool 方法可以去掉不写 ! !
测试文件不改:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = context.getBean("hello", Hello.class);
hello.getSchool().teach();
@Qualifier
如果xml文件中同一个类型的 bean 有两个或多个,这时@Autowired 既不能通过 byName 找到对应的 bean, 也不能通过 byType 找到,就需要用到 @Qualifier(value="xxx") 注解
beans.xml:
<context:annotation-config />
<bean id="school2" class="com.edward.pojo.School"></bean>
<bean id="school3" class="com.edward.pojo.School"></bean>
<bean id="hello" class="com.edward.pojo.Hello"></bean>
Hello.java:
@Resource
默认通过 byName 的方式注入,如果找不到名字,则通过 byType 实现,如果都找不到则报错。
第四阶段: 注解自动注册 bean
之前:注解实现了自动装配,但 xml 文件依然需要写 <bean>
进化: 扫描要自动装配的包,在 java 文件中通过 @Component 给Class注册 <bean>
beans.xml:
<context:component-scan base-package="com.edward.pojo"></context:component-scan>
<context:annotation-config></context:annotation-config>
Student.java:
Cat.java:
测试文件不变:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = context.getBean("student", Student.class);
student.getCat().shout();
}
}
@Value
使用了 @component 后,通过 @Value 直接给属性赋值
MyTest:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = context.getBean("student", Student.class);
String name = student.getName();
System.out.println(name);
}
}
由 @Component 衍生的注解:
@Repository 【DAO层】
@Service 【Service层】
@Controller 【controller层】
这三个注解和 @Component 的功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
第五阶段: javaConfig 配置文件
之前:XML文件配置 <context:annotation-config> 等实现注入
进化:完全不需要 XML 配置文件,全权交给 java 来做!
删掉resources目录下的xml文件
新建 myConfig.java 文件:
myConfig.java:
@Configuration
public class MyConfig {
@Bean
public Hello hello () { // 方法名相当于bean标签的id
return new Hello(); // 要注入bean的对象
}
}
Hello.java:
@Component
public class Hello {
@Value(value = "edward123")
private String name;
public String getName() {
return name;
}
}
MyTest: AnnotationConfigApplicationContext
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Hello hello = context.getBean("hello", Hello.class);
String name = hello.getName();
System.out.println(name);
}
}