前言:
package newObject;
public class Test {
public void run(){
System.out.println("Test里面的run...................");
}
}
package newObject;
public class Test1 {
public static void main(String[] args) {
Test test = new Test();
test.run();
}
}
对于上面的两段代码,在Test1类里面调了 Test里面的方法,想必大家都能看的懂,为了达到这一个目的,我们选择了在Test1类里面实例化一个Tset的对象,进行调用该方法,然而,这种代码的耦合性比较高,假设一下,如果Test的类名更改了,是不是还要到Test1的里面把Test改掉然而在以后的开发中,类会非常多,这样维护会变得非常繁琐,假设我们把它们全部放到一个容器里面,用的时候直接去容器里面找,不用的时候也无需更改,是不是更方便些呢,spring为我们提供的IOC容器就能做到。
一.IOC的核心概念
使用对象时,由主动new产生对象转换为由外部提供对象,此过程对象创建控制权转移到外部,此思想称为控制反转。Spring技术对IOC思想进行了实现,提供了一个容器,被称为IOC容器。该IOC容器就是外部。对象在该容器里面有个新的名称Bean。
二.IOC入门
- 在pom文件中导入spring的坐标(基于maven搭建项目)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
- 创建一个application.xml文件,在文件内部配置bean
<?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="test" class="newObject.Test"></bean>
<bean id="test1" class="newObject.Test1"></bean>
</beans>
以上就是将刚刚的Test和Test1类配置到IOC容器的操作。
- 验证bean的配置
package com.itheima;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
System.out.println(ctx.getBean("test"));
System.out.println(ctx.getBean("test1"));
}
}
运行程序,输出地址,就证明bean在IOC容器配置成功。
三.Bean基础配置
<bean id="test" name="userTest" class="com.itheima.UserTest" scope="singleton"></bean>
上面可以明显看的出是在定义一个bean,但仔细发现比之前定义的bean多了name属性和scope属性name属性就是指定一个别名(可以认为是除了id指定的名之外,第二个名字,通过该名字也能 获取该bean),scope属性指定的是该bean是单例还是非单例(单例:该bean为共享,用的都是 同一个,反之,非单例,spring默认为单例,这里我们一般也是用单例)。
四.Bean的三种实例化方式
- 无参构造器
我们在需要被IOC管理的类里面提供无参构造器。
package com.itheima;
/**无参构造器实例化bean*/
public class UserController {
public UserController() {
}
}
在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-->
<bean id="userController" class="com.itheima.UserController"></bean>
</beans>
这种形式也是我们最常见的形式。
- 静态工厂
我们不需要在被IOC管理的类里面提供任何东西
package com.itheima;
public class UserDao{
}
但我们需要提供一个静态工厂
package com.itheima.Config;
import com.itheima.UserDao;
/**声明一个静态工厂*/
public class OrderDaoFactory {
public static UserDao getUserDao(){
return new UserDao();
}
}
我们需要注意静态工厂无非就是随便定义一个类在类里面定义了一个方法,而方法的返回值要是我们需要被IOC管理对象 。
在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-->
<bean id="userDao" class="com.itheima.Config.OrderDaoFactory" factory-method="getUserDao"></bean>
<beans>
这个时候,class指向了静态工厂,而不是我们需要被管理的对象,factory-method指向了工厂内哪个返回值为我们需要被IOC管理对象的方法名。(了解即可)
- 实例工厂
我们不需要在被IOC管理的类里面提供任何东西
package com.itheima;
public class UserService {
}
但我们需要提供一个实例工厂
package com.itheima.Config;
import com.itheima.UserService;
/**声明一个实例工厂*/
public class OrderServiceFactory {
public UserService getUserService(){
return new UserService();
}
}
这里和静态工厂很相似,仔细观察两者的不同。
在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">
<!-- 实例工厂实例化bean1-->
<bean id="factory" class="com.itheima.Config.OrderServiceFactory"></bean>
<bean id="UserService" factory-bean="factory" factory-method="getUserService"></bean
</beans>
这里较为难理解,我们发现定义了两个bean,第一个bean,就指的是把该实例工厂定义为一个普通bean,第二个bean,我们发现没有class属性 factory-method可以参考静态工厂进行理解,而factory-bean就是定义的第一个bean的id值(了解即可)。
拓展(实例工厂的第二种写法)
基于上面的实现方式将实例工厂修改成下面这种方式
package com.itheima.Config;
import com.itheima.UserService;
import org.springframework.beans.factory.FactoryBean;
public class UserControllerFactor implements FactoryBean<UserService> {
//代替原始实例工厂创建对象的方法
public UserController getObject() throws Exception {
return new UserService();
}
public Class<?> getObjectType() {
return UserService.class;
}
}
在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-->
<bean id="Service" class="com.itheima.Config.UserControllerFactor"></bean>
</beans>
这样,我们发现xml文件里面的配置就简单了很多(推荐使用)。
五.Bean的生命周期
- 定义一个类,声明两个方法(第一种)
package com.itheima;
/**生命周期*/
public class UserTest {
public void init(){
System.out.println("bean初始化");
}
public void factor(){
System.out.println("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="usertest" class="com.itheima.UserTest" init-method="init" destroy-method="factor"></bean>
</beans>
init-method指定的方法就是在bean初始化的时候执行的方法,destory-method指定的方法就是在bean销毁前执行的方法。
- 定义一个类,实现接口(第二种)
package com.itheima;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**生命周期*/
public class UserTest implements InitializingBean, DisposableBean {
public void destroy() throws Exception {
System.out.println("bean销毁");
}
public void afterPropertiesSet() throws Exception {
System.out.println("bean初始化");
}
}
实现里面的destory()销毁和afterPropertiesSet()初始化方法,与第一种自己定义的一样。
在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="usertest" class="com.itheima.UserTest" </bean>
</beans>
在xml文件内部就无需在自己指定。
六.注解开发初体验
前言:面对上面的一些xml文件的配置,以及实例化bean的方式配置显得很繁琐,觉得还不如new的形式方便,为了更方便我们的使用spring提供了注解的开发,来结合xml文件进行使用。
- xml文件形式
package com.itheima;
/**无参构造器实例化bean*/
public class UserController {
public UserController() {
}
}
<?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-->
<bean id="userController" class="com.itheima.UserController"></bean>
</beans>
- 注解形式
package com.itheima;
import org.springframework.stereotype.Component;
/**无参构造器实例化bean*/
@Component
public class UserController {
public UserController() {
}
}
对比之下,可以明显的发现注解开发的简洁。
、