Spring
一.创建对象的方式
- 静态工厂创建对象
package com.shine.factory;
import java.io.IOException;
import java.util.Properties;
public class StaticBeanFactory {
private static Properties properties = new Properties();
static {
try {
properties.load(StaticBeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取对象的方法
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
try {
Class<?> clazz = Class.forName(properties.getProperty(beanName));
if (clazz != null){
return clazz.newInstance();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
- 实例工厂创建对象
package com.shine.factory;
import java.io.IOException;
import java.util.Properties;
public class StaticBeanFactory {
private static Properties properties = new Properties();
static {
try {
properties.load(StaticBeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取对象的方法
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
try {
Class<?> clazz = Class.forName(properties.getProperty(beanName));
if (clazz != null){
return clazz.newInstance();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
- spring创建对象
a.创建maven项目,导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
b.创建实体类,dao实现类
c.创建配置文件,编写标签类
d.测试
二.IOC(控制反转)
概述——反转了依赖关系的满足方式,之前由自己创建依赖对象,变为由工厂推送,解决了具有依赖关系的组件之间的强耦合。
强耦合的解决方法——不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)。
三.依赖注入
1.set注入
- Users.java
import java.util.Date;
/**
* 通过Spring创建Users的对象
* 使用Spring给属性赋值
*/
public class Users {
private Integer id;
private String username;
private String password;
private String sex;
private Date birthday;
public void setId(Integer id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
}
- bean.xml
bean id="users" class="com.gh.entity.Users">
<property name="id">
<value>1</value>
</property>
<property name="username" value="中国移动"></property>
<property name="password" value="10086"></property>
<property name="sex" value="男"></property>
<property name="birthday" ref="birthday"></property>
</bean>
- 测试
@Test
public void getUsers01(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
// 默认使用单例模式
Users users01 = ioc.getBean("users", Users.class);
System.out.println(users01);
}
2.构造方法注入
- bean.xml
<?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="stu01" class="com.gh.entity.Stu">
<constructor-arg name="id" value="1024"></constructor-arg>
<constructor-arg name="name" value="zhangsan"></constructor-arg>
<constructor-arg name="gender" value="male"></constructor-arg>
<constructor-arg name="height" value="1.78"></constructor-arg>
</bean>
</beans>
3.p命名空间注入
- beans.xml
- 导入命名空间依赖
xmlns:p="http://www.springframework.org/schema/p"
<bean id="user03" class="com.gh.entity.User" p:id="1004" p:userName="gh" p:password="324151" p:registerTime="2021/07/08"></bean>
4.自动注入
<?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="userService" class="com.shine.service.impl.UsersServiceImpl">
<property name="usersDao" ref="usersDao"></property>
</bean>-->
<!-- <bean id="usersDao" class="com.shine.dao.impl.UsersDaoImpl"></bean>-->
<bean id="usersDao" class="com.gh.dao.impl.UsersDaoImpl"></bean>
<bean id="usersDao0" class="com.gh.dao.impl.UsersDaoImpl"></bean>
<bean id="userService2" class="com.gh.service.impl.UsersServiceImpl" autowire="byName"></bean>
<bean id="userService3" class="com.gh.service.impl.UsersServiceImpl" autowire="byType"></bean>
</beans>
四. Bean特性
4.1 默认是单例——Spring工厂创建的对象默认使用单例模式
4.2 Bean创建时间
-
单例模式——容器创建的时候创建Bean
-
多例模式——调用getBean方法时候创建Bean,每次调用getBean都会创建新的对象
4.3 销毁时间
- 单例模式——容器关闭
- 多例模式——对象变成垃圾之后
4.4 单例、多例模式切换
- scope:singleton(单例)prototype(多例)
4.5 单例模式优缺点
- 优点:创建时间早,节省开销,提高性能
- 缺点:线程安全问题
- 解决办法:尽量使用局部变量,尽量少修改成员变量,改成多例模式
5.6 生命周期阶段
单例——bean:singleton
随工厂启动创建——构造方法 ——set方法(注入值)—— init(初始化) —— 构建完成 ——随工厂关闭销毁
多例——bean:prototype
被使用时创建 —— 构造方法—— set方法(注入值) —— init(初始化) —— 构建完成——JVM垃圾回收销毁