三种方式,分别为构造方法、静态工厂和实例化工厂
新建Module项目,选择Maven,在pom.xml导入如下依赖:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-1</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.22.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1. 构造方法
如下:有一个接口BookDao和其实现类BookDaoImpl,怎样在外部类上不使用new创建实例来使用其下的save方法。
BookDao
package com.bh.dao;
public interface BookDao {
void save();
}
BookDaoImpl
package com.bh.dao.Impl;
import com.bh.dao.BookDao;
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("数据已保存!");
}
}
在当前项目的resources文件夹下新建applicationContext.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 标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型
-->
<bean id="bookDao" class="com.bh.dao.Impl.BookDaoImpl"/>
</beans>
之后在外部类上使用这个类的save方法,如下:
package com.bh;
import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
运行结果:
假设这个BookDao是一个数据库的相关操作类,这里还有一个业务类BookService,用来调用BookDao下的save方法,实现如下:
BookService
package com.bh.service;
public interface BookService {
void save();
}
BookService实现类BookServiceImpl
package com.bh.service.Impl;
import com.bh.dao.BookDao;
import com.bh.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
bookDao.save();
}
}
在applicationContext.xml配置文件为:
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属性表示给bean起名字
class属性表示给bean定义类型
-->
<bean id="bookDao" class="com.bh.dao.Impl.BookDaoImpl"/>
<bean id="bookService" class="com.bh.service.Impl.BookServiceImpl">
<!-- property 标签表示配置当前bean的属性
name 属性表示配置哪一个具体的属性
ref 属性表示参照哪一个bean
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
【注】:在BookServiceImpl类中一定要写对应的setter方法,applicationContext.xml配置文件中property标签的name就是在BookServiceImpl私有属性bookDao,ref就是参照哪一个bean。
测试如下:
package com.bh;
import com.bh.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookservice = (BookService) ctx.getBean("bookService");
bookservice.save();
}
}
运行结果和上述相同,本质上就是调用相同的方法。
2. 静态工厂
其实就是实现一个工厂类,下有一个静态方法,用于返回某一个实例化对象,如下:
BookFactory
package com.bh.factory;
import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;
public class BookFactory {
public static BookDao getBookDao(){
return new BookDaoImpl();
}
}
配置文件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="bookDao2" class="com.bh.factory.BookFactory" factory-method="getBookDao"/>
</beans>
测试代码
package com.bh;
import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao2 = (BookDao) ctx.getBean("bookDao2");
bookDao2.save();
}
}
运行结果同上。
3. 实例工厂
和第2点一样,只不过不是用静态方法返回一个实例化对象,而是一个普通方法,如下:
BookFactory2
package com.bh.factory;
import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;
public class BookFactory2 {
public BookDao getBookDao(){
return new BookDaoImpl();
}
}
配置文件applicationContext.mxl
<?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="bookFactory2" class="com.bh.factory.BookFactory2"/>
<bean id="bookDao3" factory-method="getBookDao" factory-bean="bookFactory2"/>
</beans>
测试代码
package com.bh;
import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao3 = (BookDao) ctx.getBean("bookDao3");
bookDao3.save();
}
}
运行结果同上。
这种方式在配置文件中创建了两个bean,前一个是为后一个bean服务的,这样显得这个bean除了这个服务之外,毫无用处,于是可以对第三种方式进行改进,如下:
新建BookFactory3,让其实现接口FactoryBean,并实现其对应的方法getObject和getObjectType,如下:
BookFactory3
package com.bh.factory;
import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;
import org.springframework.beans.factory.FactoryBean;
public class BookFactory3 implements FactoryBean<BookDao> {
public BookDao getObject() throws Exception {
return new BookDaoImpl();
}
public Class<?> getObjectType() {
return BookDao.class;
}
}
在applicationContext.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="bookDao3" class="com.bh.factory.BookFactory3"/>
</beans>
在运行上述测试代码,运行结果依旧,这种方式创建的BookDao是单例的,FactoryBean接口里还有一个实现了的方法的isSingleton,默认返回true,把这个方法进行重写,返回false,就不是单例的了。