实例化方式有三种
- 默认构造
- 静态工厂
- 实例工厂
默认构造
使用默认构造需要提供默认的构造方法(如果你只写有参构造,不写无参构造会出现异常)
<bean id="myBeanFactory" class="com.spring.c_inject.c_factory.MyBeanFactory"/>
异常如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in class path resource [com/spring/a_ioc/applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.spring.a_ioc.UserServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.a_ioc.UserServiceImpl.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1163)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1107)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at com.spring.a_ioc.UserServiceImplTest.addUserByIOC2(UserServiceImplTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.spring.a_ioc.UserServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.a_ioc.UserServiceImpl.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
... 30 more
Caused by: java.lang.NoSuchMethodException: com.spring.a_ioc.UserServiceImpl.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 31 more
静态工厂
常用于整合其他框架(工具)(什么框架的话,没有经验。知道的朋友可以在评论区提供)用于生成实例对象,所有方法必须是静态的
例子
UserService代码看前一期
public class MyBeanFactory {
public static UserService createUserService(){
return new UserServiceImpl();
}
}
配置文件,细节在注释里面
<?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
class确定静态工厂全限定类名
factory-method确定静态方法名-->
<bean id="userService" class="com.spring.c_inject.b_static_factory.MyBeanFactory" factory-method="createUserService"/>
</beans>
测试代码
public class MyBeanFactoryTest {
/**
*这是传统的工厂实例化对象的方法
*/
@Test
public void createUserService() {
UserService user = MyBeanFactory.createUserService();
user.addUser();
}
/**
*这是spring实例化对象的方法
*/
@Test
public void createUserServiceBySpring() {
String src = "com/spring/c_inject/b_static_factory/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(src);
UserService user = applicationContext.getBean("userService",UserService.class);
user.addUser();
}
}
实例工厂
必须先有工厂实例对象,通过实例对象来创建对象
传统的就是先创建工厂,然后通过工厂的非静态方法来创建对象,详细看测试
配置,这里把mybeanFactory的createUserService方法改为了非静态方法需要注意
<?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="myBeanFactory" class="com.spring.c_inject.c_factory.MyBeanFactory"/>
<!--
factory-bean是实例工厂 factory-method是创建对象方法(非静态)
-->
<bean id="userService" class="com.spring.c_inject.c_factory.UserServiceImpl" factory-bean="myBeanFactory" factory-method="createUserService"/>
</beans>
测试
public class MyBeanFactoryTest {
@Test
public void createUserService() {
//创建实例工厂
MyBeanFactory myBeanFactory = new MyBeanFactory();
UserService user = myBeanFactory.createUserService();
user.addUser();
}
@Test
public void createUserServiceBySpring() {
String src = "com/spring/c_inject/c_factory/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(src);
UserService user = applicationContext.getBean("userService",UserService.class);
user.addUser();
}
}
网友评论