*注:在IDEA中我建立的Maven项目,不了解Maven的朋友能够看我以前的博客“咱们一块儿走进Maven——知己知彼”,了解Maven后能够看我以前的博客“Maven的安装与配置”,自行安装,行动起来吧。html
在pom.xml文件中添加Spring依赖和日志相关依赖java
<dependencies> <!--测试相关--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--Spring核心基础依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--日志相关--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
在main目录下面建立java和resources目录web
建立dao包,在dao包下建立TestDao接口和TestDao接口的实现类,结构以下图:正则表达式
TestDao接口代码示例:spring
package dao; public interface TestDao { public void sayHello(); }
TestDaoImpl实现类代码示例:express
package dao; public class TestDaoImpl implements TestDao{ @Override public void sayHello() { System.out.println("Hello,Spring!"); } }
在resources资源目录点击右键,依次选择New-->XML Configuration File-->Spring Config,建立applicationContext.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"> <!--把testDao对象的建立权交给Spring-->
<!-- <bean> 配置须要建立的对象
id :用于以后从Spring容器中得到实例时使用的
class :须要建立实例的全限定类名-->
<bean id="testDao" class="dao.TestDaoImpl"></bean> </beans>
建立test包,在test包下建立测试类SpringTest api
package test;
import dao.TestDao; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest {
@Test
public void demo1(){
// 以前开发,本身手写new出对象
TestDao dao= new TestDaoImpl();
dao.sayHello();
}
@Test
public void demo2() {
// 如今从spring容器中得到对象实例
// 1 、得到容器
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
// 二、得到内容 ,注意此时不须要本身new出对象了,都是从spring容器中得到
//经过容器获取testDao实例
TestDao testDao = (TestDao) application.getBean("testDao");
testDao.sayHello();
}
}
点击测试方法左侧的运行按钮,选择Run,测试代码数组
运行后控制台显示结果 app
项目运行成功!!!!!!!
class B { private A a; // B类依赖A类,B类使用A类。 } 依赖:一个对象须要使用另外一个对象。 注入:经过setter方法进行另外一个对象实例设置。
例如:
class BookServiceImpl { // 以前开发:接口 = 实现类(service和dao耦合了,写死了,知道具体的实现类是谁,那么个人具体实现类变化,那么这行代码也得跟着变) // private BookDao bookDao = new BookDaoImpl(); // spring以后(解耦:service实现类使用了dao的接口,这样就不知道具体的实现类是谁了) private BookDao bookDao; setter方法 } 模拟spring执行过程 建立service实例:BookService bookService = new BookServiceImpl(); => IoC <bean> 建立dao实例:BookDao bookDao = new BookDaoImple(); => IoC 将dao设置给service:bookService.setBookDao(bookDao); => DI <property>
具体代码实现:
实现步骤:
项目结构:
加载依赖:
在pom.xml文件中添加Spring依赖和日志相关依赖
<dependencies> <!--测试相关--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--Spring核心基础依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--日志相关--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
BookDao接口和实现类
package dao; public interface BookDao { void save(); }
package dao; public class BookDaoImpl implements BookDao { @Override public void save() { System.out.println("实现添加功能"); } }
BookService接口和实现类
package Service; public interface BookService { void addBook(); }
package Service; import dao.BookDao; import dao.BookDaoImpl; public class BookServiceImpl implements BookService { //方式一:以前,接口=实现类 //private BookDao bookDao= new BookDaoImpl(); //方式二:如今,接口+setter方法 private BookDao bookDao; public void setBookDao(BookDao bookDao){ this.bookDao=bookDao; } @Override public void addBook() { this.bookDao.save(); } }
将dao和service配置到 applicationContext.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 :用于以后从Spring容器中得到实例时使用的 class :须要建立实例的全限定类名--> <!-- 模拟spring执行过程 建立service实例:BookService bookService = new BookServiceImpl(); => IoC <bean> 建立dao实例:BookDao bookDao = new BookDaoImple(); => IoC 将dao实例设置给service实例:bookService.setBookDao(bookDao); => DI <property> <property> 用于进行属性注入 name : Bean的属性名称,经过setter方法得到 setBookDao => BookDao => bookDao ref :另外一个Bean的id值的引用 --> <!-- 建立service实例 --> <bean id="bookServiceId" class="Service.BookServiceImpl"> <!-- 将dao实例设置给service实例 --> <property name="bookDao" ref="bookDaoId"></property> <!-- 用于进行属性注入 --> </bean> <!-- 建立dao实例 --> <bean id="bookDaoId" class="dao.BookDaoImpl"></bean> </beans>
使用api测试
建立test包,在test包下建立测试类SpringTest
package test; import Service.BookService; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void Test1(){ // 以前开发,本身手写new出对象 // BookService bookService = new BookServiceImpl(); // bookService.addBook(); } @Test public void Test2(){ // 如今从spring容器中得到对象实例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 二、得到内容 ,注意此时不须要本身new出对象了,都是从spring容器中得到 BookService bookService = (BookService) applicationContext.getBean("bookServiceId"); bookService.addBook(); } }
运行后控制台显示结果
这就成功了,开心一下,经过这两个案例,多Spring有了初步的理解,加油!
api总体了解便可,以后不使用,在学习过程须要。
工厂
,用于生成任意Bean。采起延迟加载,第一次调用getBean(); 时才会初始化Bean。(即实例化对象)
采起非延时加载,当配置文件被加载时,就进行对象的实例化。
示例代码以下:
package test; import Service.BookService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; public class SpringTest { @Test public void Test1(){ // 以前开发,本身手写new出对象 // BookService bookService = new BookServiceImpl(); // bookService.addBook(); } @Test public void Test2(){ // 如今从spring容器中得到对象实例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 采起非延时加载,当配置文件被加载时,就进行对象的实例化。 // 二、得到内容 ,注意此时不须要本身new出对象了,都是从spring容器中得到 BookService bookService = (BookService) applicationContext.getBean("bookServiceId"); bookService.addBook(); } @Test public void demo3() { // 如今从spring容器中得到对象实例,使用的是BeanFactory,里面须要一个Resource,该Resource又是一个接口,须要找它的实现类ClassPathResource // 1 、得到容器 BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); // 二、得到内容 ,注意此时不须要本身new出对象了,都是从spring容器中得到 BookService bookService = (BookService) beanFactory.getBean("bookServiceId"); // 采起延迟加载,第一次调用getBean(); 时才会初始化Bean(即实例化对象)。 bookService.addBook(); } }
3种bean实例化方式:
使用默认构造方法实例化
格式:
<bean id="从Spring容器中得到实例时使用的" class="须要建立实例的全限定类名"></bean> 例如:<bean id="userServiceId" class="Service.UserServiceImpl"></bean>
示例中用到的 UserService.java 和 UserServiceImpl.java 代码同上面实例中的代码,这里再也不赘述!
在spring容器中进行配置:
applicationContext.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必需要提供默认构造方法 -->
<bean id="userServiceId" class="Service.UserServiceImpl"></bean>
</beans>
测试代码:
public class TestIoC { @Test public void demo01() { // 以前开发,本身手写new出对象 UserService userService = new UserServiceImpl(); // 直接手动建立实例 userService.addUser(); } @Test public void demo02() { // 如今从spring容器中得到对象实例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 二、得到内容 ,注意此时不须要本身new出对象了,都是从spring容器中得到 UserService userService = (UserService) applicationContext.getBean("userServiceId"); userService.addUser(); } }
使用`静态工厂方法`实例化
示例中用到的 UserService.java 和 UserServiceImpl.java 代码同上面实例中的代码,这里再也不赘述!
格式:
<bean id="" class="工厂全限定类名" factory-method="静态方法名称">
在spring容器中进行配置:
applicationContext.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 的方式 :使用静态工厂方法实例化
将自定义的静态工厂建立的实例交给spring管理
class 自定义静态工厂全限定类名
factory-method 静态方法名
-->
<bean id="userServiceId" class="Service.MyBeanFactory" factory-method="createService"></bean>
</beans>
静态工厂类代码:
public class MyBeanFactory { /** * 建立实例的静态工厂,全部的方法必须是静态的(static)。 * * @return */ public static UserService createService() { return new UserServiceImpl(); } // 还有建立其余实例的静态工厂 // ...... }
测试代码:
TestStaticFactory.java
/** * 第二种实例化Bean 的方式 :使用静态工厂方法实例化 * */ public class TestStaticFactory { @Test public void demo01() { // 之前:使用自定义的静态实例工厂 UserService userService = MyBeanFactory.createService(); userService.addUser(); } @Test public void demo02() { // 如今:使用spring 工厂:将自定义的静态工厂建立的实例交给spring管理
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userServiceId", UserService.class); // 这种方式底层会自动转换
// UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
}
注意:当使用JDK版本为1.8时,运行上面的测试代码会出现一个问题: java.lang.IllegalArgumentException,
问题解决连接:使用Junit测试一个 spring静态工厂实例化bean 的例子,全部代码都没有问题,可是出现java.lang.IllegalArgumentException异常
小结:在之后的开发中,工厂类不须要咱们去手写,由于别人已经写好了,咱们经过编写配置文件
,把别人写好的工厂类拿来,写上要用的方法名,而后把它生产后的实例给Spring存起来,之后咱们要用什么实例,跟Spring说一下,去拿就能够了。
使用`实例工厂方法`实例化
实例工厂:必须先有工厂的实例对象,而后经过实例对象去建立对象。特色:提供全部的方法都是“非静态”的。
示例中用到的 UserService.java 和 UserServiceImpl.java 代码同上面实例中的代码,这里再也不赘述!
在spring容器中进行配置:
applicationContext.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="myBeanFactoryId" class="com.itheima.c_inject.c_factory.MyBeanFactory" ></bean>
<!--经过工厂实例,得到对象 factory-bean 工厂实例名称 factory-method 普通方法名称 -->
<bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>
</beans>
静态工厂类代码:
public class MyBeanFactory { /** * 建立实例的工厂,全部方法非静态 * * @return */ public UserService createService() { return new UserServiceImpl(); } // 还有建立其余实例的工厂 // ...... }
测试代码:
TestFactory.java
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 第三种实例化Bean 的方式 :使用实例工厂方法实例化 * */ public class TestFactory { @Test public void demo01() { // 之前:使用自定义的实例工厂 // 一、建立工厂实例 MyBeanFactory myBeanFactory = new MyBeanFactory(); // 二、经过工厂实例,得到对象 UserService userService = myBeanFactory.createService(); userService.addUser(); } @Test public void demo02() { // 如今:使用spring 工厂:将自定义的实例工厂建立的实例交给spring管理
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userServiceId", UserService.class); // 这种方式底层会自动转换
// UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
}
普通bean :以前操做的都是普通bean。例如:< bean id="xxx" class="A" >
,这句代码的意思是:Spring直接建立A的实例,并返回。
FactoryBean :是一个特殊的bean,具备工厂生成对象能力
,可是只能生成特定的对象。
想要生产对象的bean 必须实现FactoryBean 接口,此接口提供方法getObject(); 用于得到特定bean。
< bean id="xxx" class="FB">
,这句代码的意思是:Spring会先建立FB实例,而后调用getObject(); 方法,并返回方法的返回值。BeanFactory 和 FactoryBean 对比?
< bean id="xxx" class="….ProxyFactoryBean">
,这句代码的意思是:得到代理对象的实例。即AOP使用。spring容器中bean元素id和name属性的区别?
在spring容器中添加如下配置:
示例:< bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl">
bean节点中id和name的区别:
区别一:
区别二:
id :id的命名要知足XML对ID属性命名规范
例如:必须以字母开始,可使用字母、数字、连字符、下划线、句话、冒号
name : 若是Bean的名称中含有特殊字符,就须要使用name属性
例如 : < bean name="# boy" class="cn.itheima.ioc.Boy"/>
由于name属性能够相同,因此后出现Bean会覆盖以前出现的同名的Bean。
总结:项目开发的时候,强烈要求用id,由于id能够表示惟一引用。
Bean 的做用域:用于肯定spring所建立bean 的实例个数。
lazy-init="true"
来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。
< bean id="xxx" class="service.UserServiceImpl" lazy-init="true">
default-lazy-init="true"
,< beans default-lazy-init="true“>
在spring容器中进行配置:
applicationContext.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="userServiceId" class="com.itheima.d_scope.UserServiceImpl" scope="prototype"></bean>
</beans>
测试代码:
TestScope.java
public class TestScope { @Test public void demo01() { // 如今:使用spring 工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = applicationContext.getBean("userServiceId", UserService.class);
// 这种方式底层会自动转换
UserService userService2 = applicationContext.getBean("userServiceId", UserService.class);
// 这种方式底层会自动转换
// 默认Bean的做用域是单例,因此打印的对象的地址是同样的
// System.out.println(userService1); // service.UserServiceImpl@2ac273d3
// System.out.println(userService2); // service.UserServiceImpl@2ac273d3
// 如今在配置文件中添加scope属性,值为prototype,此时Bean的做用域变为多例了,再次打印,输出地址不同了
System.out.println(userService1);
//service.UserServiceImpl@66480dd7
System.out.println(userService2);
//service.UserServiceImpl@52a86356
}
}
setBeanName
。setBeanFactory
)或者上下文对象(setApplicationContext
)。postProcessBeforeInitialization
。afterPropertiesSet
。
,则表示指定初始化方法 init
。postProcessAfterInitialization
。destroy
。
,则表示指定销毁方法 customerDestroy
。
目标方法执行前和执行后,将进行Bean的初始化或销毁。
示例:<bean id="xxx" class="xxx" init-method="初始化的方法名称" destroy-method="销毁的方法名称"></bean>
示例代码以下:
编写目标类代码:
UserService.java
public interface UserService { void addUser(); }
UserServiceImpl.java
public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("e_lifecycle add user"); } public void myInit() { System.out.println("个人初始化方法"); } public void myDestory() { System.out.println("个人销毁方法"); } }
在spring容器中进行配置:
applicationContext.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">
<!--
init-method 用于配置初始化方法,用于准备数据等使用场景
destroy-method 用于配置销毁方法,用于清理资源等使用场景
-->
<bean id="userServiceId" class="service.UserServiceImpl"
init-method="myInit" destroy-method="myDestory"></bean>
</beans>
编写测试代码:
public class TestLifecycle { @Test public void demo01() throws Exception { // 如今:使用spring 工厂(spring 容器)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser(); // 要想使个人销毁方法也执行,必需要求:
// 1.容器必须先close,个人销毁方法才会执行;
// 2.必须是单例的(spring所建立该bean的实例个数只有一个)即bean中的scope配置成默认便可。
// 由于此close方法在接口 ApplicationContext 中没有定义,而在实现类中提供了该方法,咱们可使用反射,由于反射最后执行的就是实现类中的方法。
applicationContext.getClass().getMethod("close").invoke(applicationContext); } }
这句代码的意思就是:把实现类提供给了spring容器。咱们来模拟这句话的意思:
before() => postProcessAfterInitialization(Object bean, String beanName) after() => postProcessBeforeInitialization(Object bean, String beanName) A a = new A(); a = B.before(a); // 将a的实例对象传递给后处理bean,能够什么都没作,也能够作一些事情,好比:生成jdk代理对象并返回给a,这样a就从实例对象变成代理对象了,此时的a就具备了AOP功能;再好比,若是把null返回给a,再用a去调用方法,就会出现空指针异常。 a.init(); a = B.after(a); // 如下是AOP演示: // 咱们如今在后处理Bean 代码执行完以后,把jdk代理对象返回给a。让a在调用addUser()以前先作一些事情 // 以前要作的事情 a.addUser(); // 在目标方法的先后能够作一些事情,例如:开启事务、提交事务、性能监控(先后时间)等等 // 以后要作的事情 a.destroy();
目标类示例代码以下:
UserService.java
public interface UserService { void addUser(); }
UserServiceImpl.java
public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("e_lifecycle add user"); } public void myInit() { System.out.println("个人初始化方法"); } public void myDestory() { System.out.println("个人销毁方法"); } }
实现类示例代码以下:
MyBeanPostProcessor.java
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("执行了前方法:" + beanName); return bean; } @Override public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("执行了后方法:" + beanName); // 传入的参数bean是咱们的目标对象,此时咱们的目标对象只有一个接口,那么咱们的代理对象也只有一个接口 // 生成jdk代理对象 return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), // 代理对象 bean.getClass().getInterfaces(), // 目标对象 new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("---开启事务---"); Object obj = method.invoke(bean, args); // 执行目标方法,本例中的目标方法是addUser System.out.println("---关闭事务---"); return obj; } }); // 代理的处理程序 } }
在spring容器中进行配置:
applicationContext.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">
<!--
init-method 用于配置初始化方法,用于准备数据等使用场景
destroy-method 用于配置销毁方法,用于清理资源等使用场景
-->
<bean id="userServiceId" class="service.UserServiceImpl"
init-method="myInit" destroy-method="myDestory"></bean>
<!-- 将后处理的实现类注册给spring -->
<bean class="com.itheima.e_lifecycle.MyBeanPostProcessor"></bean>
</beans>
测试示例代码以下:
TestLifecycle.java
public class TestLifecycle { @Test public void demo01() throws Exception { // 如今:使用spring 工厂(spring 容器) ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
// 要想使个人销毁方法也执行,必需要求:
// 1.容器必须先close,个人销毁方法才会执行;
// 2.必须是单例的(spring所建立该bean的实例个数只有一个)即bean中的scope配置成默认便可。
// 由于此close方法在接口 ApplicationContext 中没有定义,而在实现类中提供了该方法,咱们可使用反射,由于反射最后执行的就是实现类中的方法。
applicationContext.getClass().getMethod("close").invoke(applicationContext);
}
}
手工装配
或自动装配
。在实际应用中
建议使用手工装配
,由于自动装配会产生未知状况,开发人员没法预见最终的装配结果。
Bean对象类:
public class User { private Integer uid; private String username; private Integer age; public User(Integer uid, String username) { // 构造方法一 super(); this.uid = uid; this.username = username; } public User(String username, Integer age) { // 构造方法二 super(); this.username = username; this.age = age; } // 省略getter 和 setter 方法 // ......
在spring容器中进行配置:
applicationContext.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">
<!--6.5.一、构造方法注入
<constructor-arg> 用于配置构造方法的一个参数argument
name :参数的名称
value :设置普通数据
ref :设置引用数据,通常是另外一个bean 的id值
index :参数的索引号,从0开始 。若是只有索引,匹配到了多个构造方法时,默认使用第一个。
type :肯定参数类型
例如1:name属性开发中不经常使用,由于使用该属性须要关联要实例化对象的源码,不然name的值你就不知道。而通常开发中咱们咱们不会获得源码。
<constructor-arg name="username" value="李晓艺"></constructor-arg>
<constructor-arg name="age" value="26"></constructor-arg>
例如2:类型type 和 索引index (这二者结合使用)
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
注意:在开发中为了指定执行的是哪一个构造方法,通常使用index属性和type属性结合的方式。
-->
<bean id="userId" class="entity.User">
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
</beans>
在spring容器中进行配置:
applicationContext.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">
<!--6.5.二、setter方法注入
* 注入的是普通数据 时
<property name="" value="值"></property>
等效
<property name="">
<value>值</value>
</property>
* 注入的是引用数据时
<property name="" ref="另外一个bean的id"></property>
等效
<property name="">
<ref bean="另外一个bean的id"></ref>
</property>
-->
<bean id="personId" class="entity.Person">
<property name="pname" value="晓艺"></property>
<property name="age">
<value>26</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"></ref>
</property>
</bean>
<bean id="homeAddrId" class="entity.Address">
<property name="addr" value="山西运城"></property>
<property name="tel" value="911"></property