第一部分 springIoc
1、使用spring创建UserService对象
public interface UserService {
public String getInfo(String name);
}
public class UserServiceImpl implements UserService {
public String getInfo(String name) {
return name+"是冠军";
}
}
配置xml文件
<bean id="userone" name="username" class="com.qf.springioc.service.impl.UserServiceImpl"/>
测试类
创建context对象,使用@Before ,在每次程序执行的时候,这个方法都要执行一遍
private ApplicationContext context;
@Before
public void before(){
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test1(){
//获得UserService 对象
UserService userone = (UserService) context.getBean("userone");
System.out.println(userone.getInfo("鲁能"));
}
情景二:不使用id
@Test
public void test2(){
UserService bean = context.getBean(UserService.class);
String shan = bean.getInfo("泰山");
System.out.println(shan);
}
但是上面这种也有特殊情况,如果同一个接口有两个实现类,就会报错
情景三:使用name属性创建对象
@Test
public void test3(){
UserService username = (UserService) context.getBean("username");
System.out.println(username.getInfo("山东"));
}
2、如果一个类中有静态方法,静态方法返回值是一个对象,怎么获得这个返回的对象
public class StaticFactory {
public static UserService getUserService(){
UserService userService = new UserServiceImpl();
return userService;
}
}
配置文件中应该使用factory-method
<bean id="usertwo" class="com.qf.springioc.service.impl.StaticFactory" factory-method="getUserService"/>
测试类
@Test
public void test4(){
UserService usertwo = (UserService) context.getBean("usertwo");
System.out.println(usertwo.getInfo("鲁能泰山"));
}
3、对于普通工厂类中的方法中创建的对象
关键字 factory-bean factory-method
public class BeanFactory {
public UserService getBeanFactory(){
UserService userService = new UserServiceImpl();
return userService;
}
}
配置文件中
<bean id="userthree" class="com.qf.springioc.service.impl.BeanFactory"/>
<bean id="userthreetwo" factory-bean="userthree" factory-method="getBeanFactory"/>
//首先创建工厂类对象,然后再去指定获得对象的方法
// 通过实例工厂模式创建对象,我们首先需要一个工厂对象
//factory-bean 指的就是工厂对象的id
//factory-method 在工厂创建对象的方法
//BeanFactory beanFactory =new BeanFactory()
// UserService service=beanFactory.getUserService()
测试类
@Test
public void test5(){
UserService userthree = (UserService) context.getBean("userthreetwo");
System.out.println(userthree.getInfo("鲁能泰山"));
}
4、对于属性scope的运用,scope默认是singleton
scope中还有 request 一次请求一个,和其他框架整合的时候使用
session 一次会话一个
配置文件为
<!--探讨scope属性的作用,默认是singleton-->
<bean id="userfour" class="com.qf.springioc.service.impl.UserServiceImpl2" scope="prototype"/>
<bean id="userfourtwo" class="com.qf.springioc.service.impl.UserServiceImpl2" scope="singleton"/>
测试类
@Test
public void test6(){
UserService userone = (UserService) context.getBean("userfour");
UserService usertwo = (UserService) context.getBean("userfour");
System.out.println("如果是prototype,则创建的两个对象的关系式========》" + (userone == usertwo));
UserService userthree = (UserService) context.getBean("userfourtwo");
UserService userfour = (UserService) context.getBean("userfourtwo");
System.out.println("如果是singleton,则创建的两个对象的关系式========" + (userthree == userfour));
}
测试结果为:
如果是prototype,则创建的两个对象的关系式========》false
如果是singleton,则创建的两个对象的关系式========true
5、使用 init() 和 destory() 方法
public class UserServiceImpl3 {
public String getSuccess(){
System.out.println("鲁能是冠军");
return null;
}
public void init(){
System.out.println("对象创建了");
}
public void destory(){
System.out.println("对象销毁了");
}
}
配置文件的写法
<!--初始方法和销毁方法的执行-->
<bean id="userfive" class="com.qf.springioc.service.impl.UserServiceImpl3" init-method="init" scope="singleton" destroy-method="destory"/>
<bean id="userfivetwo" class="com.qf.springioc.service.impl.UserServiceImpl3" init-method="init" destroy-method="destory" scope="prototype"/>
测试类
UserServiceImpl3 userfive = (UserServiceImpl3) context.getBean("userfive");
userfive.getSuccess();
((ClassPathXmlApplicationContext) context).destroy();
这样的测试结果是:
对象创建了
鲁能是冠军
对象销毁了
但是如果scope使用prototype
测试类
UserServiceImpl3 userfivetwo = (UserServiceImpl3) context.getBean("userfivetwo");
userfivetwo.getSuccess();
((ClassPathXmlApplicationContext) context).destroy();
测试结果:
对象创建了
对象创建了
鲁能是冠军
对象销毁了
发现对象创建了两次,只是销毁了一次,所以得出结论:
init-method 创建对象后执行的方法 ,当对象是多例的时候,必须获取对象的时候才会执行
destroy-method 对象销毁的时候执行的方法, 触发条件, 1对象必须是单例 2 必须执行容器的销毁方法
创建两次是因为对象是在加载配置文件的时候就创建了,而执行测试类的时候又创建了对象,所以就执行了两次init方法
第二部分,使用注解的方式实现ioc
1、@Component
首先看注解的源代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
实体类
public interface UserService {
public String getInfo();
}
@Component
public class UserServiceImpl implements UserService {
public String getInfo() {
return "再接再厉";
}
}
配置文件
<!--开启包扫描-->
<context:component-scan base-package="com.qf.springioc.anno.service"/>
测试类
private ApplicationContext context;
@Before
public void before(){
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test1(){
UserService bean = context.getBean(UserServiceImpl.class);
System.out.println(bean.getInfo());
}
2、如果一个接口有多个实现类
@Service("us1")
public class UserServiceImpl implements UserService {
public String getInfo() {
return "再接再厉";
}
}
@Service("us2")
public class UserServiceImpl2 implements UserService {
public String getInfo() {
return "下年就是我们的了";
}
}
测试类
@Test
public void test2(){
UserService us1 = (UserService) context.getBean("us1");
System.out.println(us1.getInfo());
UserService us2 = (UserService) context.getBean("us2");
System.out.println(us2.getInfo());
}