spring-IOC
笔记
传统的业务实现
/**
* dao接口
*/
public interface UserDao {
void getUser();
}
/**
* 实现类1
*/
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("getUser方法");
}
}
/**
* 业务层接口
*/
public interface UserService {
void getUser();
}
/**
* 业务实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
public void getUser() {
userDao.getUser();
}
}
/**
* 测试类
*/
@Test
public void test(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserOracleImpl());
userService.getUser();
}
输出:
getUser方法
当需要修改业务更换dao接口的时候,我们需要修改源代码
于是我们
1.添加一个dao实现类
2.修改业务实现类
3.其他不变
/**
* 实现类2
*/
public class UserDaoMysqlImpl implements UserDao {
public void getUser() {
System.out.println("mysql的实现");
}
}
/**
* 业务实现类
*/
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
private UserDao userDao = new UserDaoMysqlImpl();
public void getUser() {
userDao.getUser();
}
}
输出:
mysql的实现
如果业务需求更换,需要再换加一种dao实现,那么我们也是一样的操作
/**
* 实现类3
*/
public class UserOracleImpl implements UserDao{
public void getUser() {
System.out.println("Oracle的实现");
}
}
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
// private UserDao userDao = new UserDaoMysqlImpl();
private UserDao userDao = new UserOracleImpl();
public void getUser() {
userDao.getUser();
}
}
输出: Oracle的实现
一种好的解决方式是:
/**
* 业务实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
/** 手动使用set注入的方式,实现可用动态更改dao实现类 */
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
@Test
public void test(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImpl());
// userService.setUserDao(new UserDaoMysqlImpl());
// userService.setUserDao(new UserOracleImpl());
userService.getUser();
}
组合对象,通过set方法,当我们需要什么实现的时候,再设置(通过组合解耦)
spring如何解耦
/**
* dao接口
*/
public interface UserDao {
void getUser();
}
/**
* 实现类1
*/
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("getUser方法");
}
}
/**
* 实现类2
*/
public class UserDaoMysqlImpl implements UserDao {
public void getUser() {
System.out.println("mysql的实现");
}
}
/**
* 实现类3
*/
public class UserOracleImpl implements UserDao{
public void getUser() {
System.out.println("Oracle的实现");
}
}
/**
* 业务层接口
*/
public interface UserService {
void getUser();
}
/**
* 业务实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
/** 手动使用set注入的方式,实现可用动态更改dao实现类 */
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
resources/application.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">
<!--使用spring来创建bean-->
<bean id="userDao" class="gg.dao.UserDaoImpl"/>
<bean id="userDaoMysql" class="gg.dao.UserDaoMysqlImpl"/>
<bean id="userOracle" class="gg.dao.UserOracleImpl"/>
<bean id="userService" class="gg.service.UserServiceImpl">
<!-- <property name="userDao" ref="userDaoMysql"/>-->
<property name="userDao" ref="userOracle"/>
<!-- <property name="userDao" ref="userDao"/>-->
</bean>
</beans>
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class);
userService.getUser();
}
输出:
Oracle的实现
通过spring管理bean,我们只需要在bean中配置不同的dao实现就可以轻轻松松应对多变的需求
spring使用解析
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
public class User {
private String name;
public User() {
System.out.println("使用了无参构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name = " + name);
}
}
<?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来创建bean
默认使用了无参构造方法来创建对象
相当于执行了
public User() {
System.out.println("使用了无参构造方法");
}
-->
<bean id="user" class="com.gg.entity.User">
<property name="name" value="小明"/>
</bean>
</beans>
@Test
public void test(){
// 创建对象调用无参构造方法
User user = new User();
// 没有调用setName方法,输出 name = null
user.show();
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
User user1 = context.getBean("user", User.class);
// spring的xml文件中管理注入了name属性,输出 name = 小明
user1.show();
}
输出:
使用了无参构造方法
name = null
使用了无参构造方法
name = 小明
可以看到,用spring管理的bean对象其实是调用了对象的无参构造方法
<property name="name" value="小明"/>
输出中,name = 小明 其实也是调用了User类中的setName方法
<!--
使用spring来创建bean
相当于:User user = new User()
-->
<bean id="user" class="com.gg.entity.User">
<!--
property采用的是set注入,实体去掉了setName就会报红
相当于:user.setName("小明")
-->
<property name="name" value="小明"/>
</bean>
怎么证明呢?
我们把setName方法注释掉

编辑器提示我们创建一个setName方法,所以

点击红框idea在User类中添加了一个setName方法(但是需要我们实现)

所以的确证明spring中管理注册bean的property就是通过setXXX方法实现的
向spring再进一步
1.使用构造器下标方式注入属性
public class User { private String name; // 添加一个字段,理解参数顺序的bean创建 private int age; /** * 干掉无参构造方法,创建一个有参数的构造方法 * @return */ public User() { System.out.println("使用了无参构造方法"); } public User(String name,int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void show(){ System.out.println("name = " + name); } } <!--1.使用构造器下标方式注入--> <bean id="user" class="com.gg.entity.User"> <!-- public User(String name,int age){ 索引从0开始 --> <constructor-arg index="0" value="小明1"/> <constructor-arg index="1" value="21"/> </bean> @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); User user1 = context.getBean("user", User.class); // 通过constructor-arg方法index注入 System.out.println("user1.getName() = " + user1.getName()); System.out.println("user1.getAge() = " + user1.getAge()); } 输出: user1.getName() = 小明1 user1.getAge() = 21
2.使用参数类型注入属性
public User(String name,int age){
this.name = name;
this.age = age;
}
<!--2.使用参数类型注入-->
<bean id="user" class="com.gg.entity.User">
<constructor-arg type="java.lang.String" value="小明2"/>
<constructor-arg type="int" value="22"/>
</bean>
输出: user1.getName() = 小明2 user1.getAge() = 22
3.使用参数名设置
<!--3.使用参数名来设置-->
<bean id="user" class="com.gg.entity.User">
<constructor-arg name="name" value="小明3"/>
<constructor-arg name="age" value="23"/>
</bean>
输出:
user1.getName() = 小明3
user1.getAge() = 23
以上笔记内容来源B站狂神说的视频前6节.
时间花在哪里,成就就在哪里

浙公网安备 33010602011771号