構成
Springでは、Beanインスタンスの設定にはxml設定方法またはアノテーション(Annotation)設定方法が一般的に使用されます。
XML設定
XML 設定には、リフレクション モード、ファクトリ メソッド モード、ファクトリ Bean モードの 3 つの方法があります。
リフレクション モード: Bean のクラス属性値を指定してオブジェクトを作成することを指します (最も一般的に使用され、前の記事ではこのモードを使用しています) ファクトリ メソッド モード: リフレクション メカニズムを通じて Factory クラスを取得し、その Factory クラスを使用してオブジェクトを作成することを指します Factory Bean モード : FactoryBean インターフェイスで getObject() メソッドを実装することによって Bean オブジェクト インスタンスを返すことを
指し
ます。通常、Factory Bean パターンは、サードパーティのフレームワークで Bean オブジェクトを構成するために使用されます。
反射モード
リフレクション モードでは、Bean 設定で Bean オブジェクトの完全なクラス名を設定する必要があります。
<bean id="beanObject" class="cn.edu.springdemo.beanDemo.beanObject" p:instance="beanObject" />
ファクトリメソッドパターン
ファクトリ メソッドは、静的ファクトリ メソッドとインスタンス ファクトリ メソッドに分けられます。ファクトリ メソッド パターンは理解しやすいです。
静的ファクトリ メソッドは、 Factory クラス自体をインスタンス化する必要がなく、オブジェクトを作成するための静的メソッドを提供することを意味します。
簡単な例:
サブジェクト クラスを作成します。
package cn.edu.springdemo.beanDemo;
//学科类
public class Discipline {
private int id;
private String discipline;
public Discipline() {
super();
}
public Discipline(int id, String discipline) {
this.id = id;
this.discipline = discipline;
}
public int getId() {
return id;
}
public String getDiscipline() {
return discipline;
}
public void setId(int id) {
this.id = id;
}
public void setDiscipline(String discipline) {
this.discipline = discipline;
}
@Override
public String toString() {
return "Discipline{" +
"id=" + id +
", discipline='" + discipline + '\'' +
'}';
}
}
サブジェクト クラスに対応する静的ファクトリ クラスを作成します。
package cn.edu.springdemo.beanDemo;
import java.util.HashMap;
import java.util.Map;
public class DisciplineStaticFactory {
private static Map<Integer,Discipline> map = new HashMap<Integer, Discipline>();
//静态 bean 容器,存储学科类对象的集合
static {
map.put(1,new Discipline(20230502,"计算机"));
map.put(2,new Discipline(20230504,"数学"));
map.put(3,new Discipline(20230506,"英语"));
}
//提供一个静态方法,根据其 id 获取对应的对象
public static Discipline getDiscipline(int id) {
return map.get(id);
}
}
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">
<!-- id为学科类的一个实例;但 class 属性指向的是静态工厂类;factory-method 属性指向的是静态工厂类的静态方法 -->
<bean id="math" class="cn.edu.springdemo.beanDemo.DisciplineStaticFactory"
factory-method="getDiscipline">
<!-- 给静态工厂类的静态方法传递参数 -->
<constructor-arg value="2"></constructor-arg>
</bean>
</beans>
試験結果:
package cn.edu.springdemo.test;
import cn.edu.springdemo.beanDemo.Discipline;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AdminTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanConfiguration.xml");
Discipline discipline = (Discipline) applicationContext.getBean("math");
System.out.println(discipline);
}
}
結果を図に示します。
インスタンス ファクトリ メソッドとは、 getBean メソッドを呼び出して、インスタンス ファクトリ オブジェクトを通じて Bean オブジェクトを取得することを指します。
簡単な例:
サブジェクト クラスと同じように、サブジェクト クラスに対応するインスタンス ファクトリ クラスを作成します。
package cn.edu.springdemo.beanDemo;
import java.util.HashMap;
import java.util.Map;
public class DisciplineInstanceFactory {
private Map<Integer,Discipline> map = new HashMap<>();
public void setMap(Map<Integer, Discipline> map) {
this.map = map;
}
//根据其 key 获取对应的对象
public Discipline getDiscipline(int key){
return map.get(key);
}
}
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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置工厂实例 -->
<bean id="disciplineInstanceFactory" class="cn.edu.springdemo.beanDemo.DisciplineInstanceFactory">
<property name="map">
<map>
<entry key="1">
<bean class="cn.edu.springdemo.beanDemo.Discipline" p:id="20230502" p:discipline="计算机" />
</entry>
<entry key="2">
<bean class="cn.edu.springdemo.beanDemo.Discipline" p:id="20230504" p:discipline="数学" />
</entry>
<entry key="3">
<bean class="cn.edu.springdemo.beanDemo.Discipline" p:id="20230506" p:discipline="英语" />
</entry>
</map>
</property>
</bean>
<!-- 配置获取相应的实例 -->
<bean id="math" factory-bean="disciplineInstanceFactory" factory-method="getDiscipline">
<constructor-arg value="2"></constructor-arg>
</bean>
</beans>
結果を図に示します。
ファクトリービーンパターン
Factory Bean インターフェースは、getObject()、getObjectType()、および isSingleton() の 3 つのメソッドを含む Factory Bean モードで実装する必要があります。
簡単な例:
サブジェクト クラスと同様に、Factory Bean インターフェイス実装クラスを作成します。
package cn.edu.springdemo.beanDemo;
import org.springframework.beans.factory.FactoryBean;
public class DisciplineFactoryBean implements FactoryBean<Discipline> {
private int id;
private String discipline;
//set 方法
public void setId(int id) {
this.id = id;
}
public void setDiscipline(String discipline) {
this.discipline = discipline;
}
//返回配置的 bean 对象实例
@Override
public Discipline getObject() throws Exception {
return new Discipline(id,discipline);
}
//返回配置的 bean 对象的类型
@Override
public Class<?> getObjectType() {
return Discipline.class;
}
//是否为单例
@Override
public boolean isSingleton() {
return true;
}
}
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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通过 FactoryBean 配置 bean 实例,getObject() 方法返回 -->
<bean id="math" class="cn.edu.springdemo.beanDemo.DisciplineFactoryBean" p:id="20230514" p:discipline="math" />
</beans>
結果を図に示します。
さらに、Quartz フレームワーク (サードパーティ フレームワーク) は、Factory Bean パターンを使用して Spring に統合されます。Quartz は、完全に Java で書かれたオープンソースのジョブ スケジューリング フレームワークで、10、数百、さらには数万のジョブを実行する単純なプログラムまたは複雑なプログラムの作成に使用できます。
簡単な例:
まず、pom.xml に次の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>2.0.6</version>
<type>jar</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
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">
<!-- 定义工作任务Job -->
<bean name="quartzJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- 指定 Job 名称 -->
<property name="name" value="QuartzJob" />
<!-- 指定 Job 分组 -->
<property name="group" value="QuartzJobGroup" />
<!-- 指定 Job 接口实现类 -->
<property name="jobClass" value="cn.edu.springdemo.beanDemo.QuartzJob" />
<!-- 指定 value 值必须为 true ,否则 Job 执行完成后不会再继续 -->
<property name="durability" value="true" />
<!-- 指定 spring 容器的 Key -->
<property name="applicationContextJobDataKey" value="QuartzJob" />
</bean>
<!-- 定义与工作任务绑定的触发器Trigger -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 指定 Trigger 名称 -->
<property name="name" value="CronTrigger" />
<!-- 指定 Trigger 分组 -->
<property name="group" value="CronTriggerGroup" />
<!-- 指定 Trigger 绑定的工作任务 -->
<!-- 多个工作任务用 jobDataMap -->
<property name="jobDetail" ref="quartzJob" />
<!-- 指定 CronExpression 表达式,每隔多长时间执行一次 -->
<!--
写法:秒 分 时 日 月 周 年
通配符:*表示所有值;
?表示不定值;
-表示区间;
,表示指定多个值;
/表示从某个时间开始,每隔一段时间触发一次
-->
<!-- 从十秒开始,每隔8秒触发一次 -->
<property name="cronExpression" value="10/8 * * * * ?" />
</bean>
<!-- 定义调度器,将 Trigger 注册到 Scheduler -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
</beans>
Job インターフェースの別の実装クラスを作成します。
package cn.edu.springdemo.beanDemo;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时执行的工作任务");
}
}
試験結果:
package cn.edu.springdemo.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
public class QuartzJobTest {
public static void main(String[] args) {
ApplicationContext QuartzJob = new ClassPathXmlApplicationContext("QuartzJob.xml");
SchedulerFactoryBean scheduler = QuartzJob.getBean(SchedulerFactoryBean.class);
scheduler.start();
}
}
結果を図に示します。