UserDao/UserDaoImpl/UserOhterSqlDaoImpl
UserService/UserServiceImpl
UserServiceImpl{
UserDao userDao = new UserDaoImpl(); //这种对象实例方式会用户的调佣不同而经常修改
UserDao = new UserOhterSqlDaoImpl();
}
//所以创建对象不该由这里的service去决定,而是从外界传入,让调用方去实例实现对象,传入本方法中,从而保证代码不用修改也能做到适应
在调用service方法是注意:有强转现现象,子类自己的方法,不能通过父类变量调用,即多态父类使用子类独有的方法要强转
UserDao userDao = null;
public void setUserDao(UserDao userDao){
this.userDao = userDao
}
TiP:在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。为了方便理解和描述,我们可以将前者称为“调用者”,将后者称为“被调用者”。也就是说,调用者掌握着被调用者对象创建的控制权。
但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里的,其大致步骤如下。
- 开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 标签、在 Java 类上使用 @Component 注解等。
- Spring 启动时,IoC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IoC 容器创建并管理的对象被称为 Spring Bean。
- 当我们想要使用某个 Bean 时,可以直接从 IoC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法),而不需要手动通过代码(例如 new Obejct() 的方式)创建。
- IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IoC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IoC 容器创建它所需要的对象(Bean),使系统耦合性降低,让开发更加专注业务的实现,这就是IOC的原型
- 这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IoC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。
设计模式的本质不是为了消除变化,而是为了将变化集中在一个地方
控制反转:核心思想就是由 Spring 负责对象的创建。在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。
public class Hello {
private String message;
public Hello() {
}
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {return false;}
Hello hello = (Hello) o;
return message != null ? message.equals(hello.message) : hello.message == null;
}
@Override
public int hashCode() {
return message != null ? message.hashCode() : 0;
}
@Override
public String toString() {
return "Hello{" +
"message='" + message + '\'' +
'}';
}
}
<?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">
<!--使用spring来创建对象,在spring这些都称为bean
相当于new对象
id ==对象名
class== 对象类型
property:set属性
message:set方法中的参数名
-->
<bean id="hello" class="com.zk.pojo.Hello">
<!--value:具体的值,基本数据类型
ref:引用spring容器中已经创建好的值 -->
<property name="message" value="hello zk!"/>
</bean>
</beans>
@Test
public void TestDemo01(){
//获取spring的ApplicationContext上下文对象,即spring容器
//参数可以传多个
//解析bean.xml文件,生成管理相应的bean对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Beans.xml");
//getBean:参数为spring配置文件中bean的id
//这里不强转,也可以在第二个参数传入类型,类似mybatis
//**id前添加&获取工厂
Hello hello = applicationContext.getBean("hello", Hello.class);
System.out.println(hello.getMessage());
}
hello zk!
注意存在的问题:
xml依赖注入arg是通过构造函数,property是通过seter方法,name属性要和实体类的属性名一致
spring容器调用无参构造器创建队像,然后用set注入,所以实体类需要无参构造器。若没有无参构造,容器通过反射创建对象(Class对象的newInstance()方法默认调用的是无参构造)会失败
没spring托管叶子:XML顶部的警告:配置上下文
public interface Trst {
default void test() {
System.out.println("方法体");
}
}
改配置文件需要需要知道加载机制是热加载还是冷加载
<property name="message" value="hello zk!"/>