Spring定时器的两种实现方式一(timer)
2011-05-20 20:05
357 查看
有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz。
1.Java Timer定时
相信做软件的朋友都有这样的经历,我的软件是不是少了点什么东西呢?比如定时任务啊,
就拿新闻发布系统来说,如果新闻的数据更新太快,势必涉及一个问题,这些新闻不能由人工的去发布,应该让系统自己发布,这就需要用到定时定制任务了,以前定制任务无非就是设计一个Thread,并且设置运行时间片,让它到了那个时间执行一次,就ok了,让系统启动的时候启动它,想来也够简单的。不过有了spring,我想这事情就更简单了。
看看spring的配置文件,想来就只有这个配置文件了
xml 代码
<bean id="infoCenterAutoBuildTask"
class="com.teesoo.teanet.scheduling.InfoCenterAutoBuildTask">
<property name="baseService" ref="baseService" />
<property name="htmlCreator" ref="htmlCreator" />
</bean>
<bean id="scheduledTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!-- wait 10 seconds before starting repeated execution -->
<property name="delay" value="10000" />
<!-- run every 50 seconds -->
<property name="period" value="1000000" />
<property name="timerTask" ref="infoCenterAutoBuildTask" />
</bean>
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<!-- see the example above -->
<ref bean="scheduledTask" />
</list>
</property>
</bean>
上面三个配置文件中只有一个配置文件是涉及到您自己的class的,其他的都是spring的类。很简单吧
我们只需要涉及一个class让他继承java.util.TimerTask;
java 代码
BaseTask extends java.util.TimerTask {
//用户只需要实现这个方面,把自己的任务放到这里
public void run(){
}
}
下面让我们来看看 spring的源代码
java 代码
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.timer;
import java.util.TimerTask;
/**
* JavaBean that describes a scheduled TimerTask, consisting of
* the TimerTask itself (or a Runnable to create a TimerTask for)
* and a delay plus period. Period needs to be specified;
* there is no point in a default for it.
*
* <p>The JDK Timer does not offer more sophisticated scheduling
* options such as cron expressions. Consider using Quartz for
* such advanced needs.
*
* <p>Note that Timer uses a TimerTask instance that is shared
* between repeated executions, in contrast to Quartz which
* instantiates a new Job for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see java.util.TimerTask
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
*/
public class ScheduledTimerTask {
private TimerTask timerTask;
private long delay = 0;
private long period = 0;
private boolean fixedRate = false;
/**
* Create a new ScheduledTimerTask,
* to be populated via bean properties.
* @see #setTimerTask
* @see #setDelay
* @see #setPeriod
* @see #setFixedRate
*/
public ScheduledTimerTask() {
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the TimerTask to schedule
*/
public ScheduledTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(TimerTask timerTask, long delay) {
this.timerTask = timerTask;
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(TimerTask timerTask, long delay, long period, boolean fixedRate) {
this.timerTask = timerTask;
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the Runnable to schedule as TimerTask
*/
public ScheduledTimerTask(Runnable timerTask) {
setRunnable(timerTask);
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(Runnable timerTask, long delay) {
setRunnable(timerTask);
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(Runnable timerTask, long delay, long period, boolean fixedRate) {
setRunnable(timerTask);
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Set the Runnable to schedule as TimerTask.
* @see DelegatingTimerTask
*/
public void setRunnable(Runnable timerTask) {
this.timerTask = new DelegatingTimerTask(timerTask);
}
/**
* Set the TimerTask to schedule.
*/
public void setTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Return the TimerTask to schedule.
*/
public TimerTask getTimerTask() {
return timerTask;
}
/**
* Set the delay before starting the task for the first time,
* in milliseconds. Default is 0, immediately starting the
* task after successful scheduling.
*/
public void setDelay(long delay) {
this.delay = delay;
}
/**
* Return the delay before starting the job for the first time.
*/
public long getDelay() {
return delay;
}
/**
* Set the period between repeated task executions, in milliseconds.
* Default is 0, leading to one-time execution. In case of a positive
* value, the task will be executed repeatedly, with the given interval
* inbetween executions.
* <p>Note that the semantics of the period vary between fixed-rate
* and fixed-delay execution.
* @see #setFixedRate
*/
public void setPeriod(long period) {
this.period = period;
}
/**
* Return the period between repeated task executions.
*/
public long getPeriod() {
return period;
}
/**
* Set whether to schedule as fixed-rate execution, rather than
* fixed-delay execution. Default is "false", i.e. fixed delay.
* <p>See Timer javadoc for details on those execution modes.
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
*/
public void setFixedRate(boolean fixedRate) {
this.fixedRate = fixedRate;
}
/**
* Return whether to schedule as fixed-rate execution.
*/
public boolean isFixedRate() {
return fixedRate;
}
}
说实话这个类也没什么,只是简单的包装了我们的timertask,里面也就只有几个属性,一个是时间片,一个是任务等。
真正运行我们的任务的类是:
java 代码
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.timer;
import java.util.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* FactoryBean that sets up a JDK 1.3+ Timer and exposes it for bean references.
*
* <p>Allows for registration of ScheduledTimerTasks, automatically starting
* the Timer on initialization and cancelling it on destruction of the context.
* In scenarios that just require static registration of tasks at startup,
* there is no need to access the Timer instance itself in application code.
*
* <p>Note that Timer uses a TimerTask instance that is shared between
* repeated executions, in contrast to Quartz which instantiates a new
* Job for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see ScheduledTimerTask
* @see java.util.Timer
* @see java.util.TimerTask
*/
public class TimerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private ScheduledTimerTask[] scheduledTimerTasks;
private boolean daemon = false;
private Timer timer;
/**
* Register a list of ScheduledTimerTask objects with the Timer that
* this FactoryBean creates. Depending on each SchedulerTimerTask's
* settings, it will be registered via one of Timer's schedule methods.
* @see java.util.Timer#schedule(java.util.TimerTask, long)
* @see java.util.Timer#schedule(java.util.TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long)
*/
public void setScheduledTimerTasks(ScheduledTimerTask[] scheduledTimerTasks) {
this.scheduledTimerTasks = scheduledTimerTasks;
}
/**
* Set whether the timer should use a daemon thread,
* just executing as long as the application itself is running.
* <p>Default is "false": The timer will automatically get cancelled on
* destruction of this FactoryBean. Hence, if the application shuts down,
* tasks will by default finish their execution. Specify "true" for eager
* shutdown of threads that execute tasks.
* @see java.util.Timer#Timer(boolean)
*/
public void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public void afterPropertiesSet() {
logger.info("Initializing Timer");
this.timer = createTimer(this.daemon);
// Register all ScheduledTimerTasks.
if (this.scheduledTimerTasks != null) {
for (int i = 0; i < this.scheduledTimerTasks.length; i++) {
ScheduledTimerTask scheduledTask = this.scheduledTimerTasks[i];
if (scheduledTask.getPeriod() > 0) {
// repeated task execution
if (scheduledTask.isFixedRate()) {
this.timer.scheduleAtFixedRate(
scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
else {
this.timer.schedule(
scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
}
else {
// One-time task execution.
this.timer.schedule(scheduledTask.getTimerTask(), scheduledTask.getDelay());
}
}
}
}
/**
* Create a new Timer instance. Called by <code>afterPropertiesSet</code>.
* Can be overridden in subclasses to provide custom Timer subclasses.
* @param daemon whether to create a Timer that runs as daemon thread
* @return a new Timer instance
* @see #afterPropertiesSet()
* @see java.util.Timer#Timer(boolean)
*/
protected Timer createTimer(boolean daemon) {
return new Timer(daemon);
}
public Object getObject() {
return this.timer;
}
public Class getObjectType() {
return Timer.class;
}
public boolean isSingleton() {
return true;
}
/**
* Cancel the Timer on bean factory shutdown, stopping all scheduled tasks.
* @see java.util.Timer#cancel()
*/
public void destroy() {
logger.info("Cancelling Timer");
this.timer.cancel();
}
}
这个类就是运行我们任务的类了,我们可以定制N个任务,只需要塞到这里就ok了
1.Java Timer定时
相信做软件的朋友都有这样的经历,我的软件是不是少了点什么东西呢?比如定时任务啊,
就拿新闻发布系统来说,如果新闻的数据更新太快,势必涉及一个问题,这些新闻不能由人工的去发布,应该让系统自己发布,这就需要用到定时定制任务了,以前定制任务无非就是设计一个Thread,并且设置运行时间片,让它到了那个时间执行一次,就ok了,让系统启动的时候启动它,想来也够简单的。不过有了spring,我想这事情就更简单了。
看看spring的配置文件,想来就只有这个配置文件了
xml 代码
<bean id="infoCenterAutoBuildTask"
class="com.teesoo.teanet.scheduling.InfoCenterAutoBuildTask">
<property name="baseService" ref="baseService" />
<property name="htmlCreator" ref="htmlCreator" />
</bean>
<bean id="scheduledTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!-- wait 10 seconds before starting repeated execution -->
<property name="delay" value="10000" />
<!-- run every 50 seconds -->
<property name="period" value="1000000" />
<property name="timerTask" ref="infoCenterAutoBuildTask" />
</bean>
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<!-- see the example above -->
<ref bean="scheduledTask" />
</list>
</property>
</bean>
上面三个配置文件中只有一个配置文件是涉及到您自己的class的,其他的都是spring的类。很简单吧
我们只需要涉及一个class让他继承java.util.TimerTask;
java 代码
BaseTask extends java.util.TimerTask {
//用户只需要实现这个方面,把自己的任务放到这里
public void run(){
}
}
下面让我们来看看 spring的源代码
java 代码
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.timer;
import java.util.TimerTask;
/**
* JavaBean that describes a scheduled TimerTask, consisting of
* the TimerTask itself (or a Runnable to create a TimerTask for)
* and a delay plus period. Period needs to be specified;
* there is no point in a default for it.
*
* <p>The JDK Timer does not offer more sophisticated scheduling
* options such as cron expressions. Consider using Quartz for
* such advanced needs.
*
* <p>Note that Timer uses a TimerTask instance that is shared
* between repeated executions, in contrast to Quartz which
* instantiates a new Job for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see java.util.TimerTask
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
*/
public class ScheduledTimerTask {
private TimerTask timerTask;
private long delay = 0;
private long period = 0;
private boolean fixedRate = false;
/**
* Create a new ScheduledTimerTask,
* to be populated via bean properties.
* @see #setTimerTask
* @see #setDelay
* @see #setPeriod
* @see #setFixedRate
*/
public ScheduledTimerTask() {
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the TimerTask to schedule
*/
public ScheduledTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(TimerTask timerTask, long delay) {
this.timerTask = timerTask;
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(TimerTask timerTask, long delay, long period, boolean fixedRate) {
this.timerTask = timerTask;
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the Runnable to schedule as TimerTask
*/
public ScheduledTimerTask(Runnable timerTask) {
setRunnable(timerTask);
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(Runnable timerTask, long delay) {
setRunnable(timerTask);
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(Runnable timerTask, long delay, long period, boolean fixedRate) {
setRunnable(timerTask);
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Set the Runnable to schedule as TimerTask.
* @see DelegatingTimerTask
*/
public void setRunnable(Runnable timerTask) {
this.timerTask = new DelegatingTimerTask(timerTask);
}
/**
* Set the TimerTask to schedule.
*/
public void setTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Return the TimerTask to schedule.
*/
public TimerTask getTimerTask() {
return timerTask;
}
/**
* Set the delay before starting the task for the first time,
* in milliseconds. Default is 0, immediately starting the
* task after successful scheduling.
*/
public void setDelay(long delay) {
this.delay = delay;
}
/**
* Return the delay before starting the job for the first time.
*/
public long getDelay() {
return delay;
}
/**
* Set the period between repeated task executions, in milliseconds.
* Default is 0, leading to one-time execution. In case of a positive
* value, the task will be executed repeatedly, with the given interval
* inbetween executions.
* <p>Note that the semantics of the period vary between fixed-rate
* and fixed-delay execution.
* @see #setFixedRate
*/
public void setPeriod(long period) {
this.period = period;
}
/**
* Return the period between repeated task executions.
*/
public long getPeriod() {
return period;
}
/**
* Set whether to schedule as fixed-rate execution, rather than
* fixed-delay execution. Default is "false", i.e. fixed delay.
* <p>See Timer javadoc for details on those execution modes.
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
*/
public void setFixedRate(boolean fixedRate) {
this.fixedRate = fixedRate;
}
/**
* Return whether to schedule as fixed-rate execution.
*/
public boolean isFixedRate() {
return fixedRate;
}
}
说实话这个类也没什么,只是简单的包装了我们的timertask,里面也就只有几个属性,一个是时间片,一个是任务等。
真正运行我们的任务的类是:
java 代码
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.timer;
import java.util.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* FactoryBean that sets up a JDK 1.3+ Timer and exposes it for bean references.
*
* <p>Allows for registration of ScheduledTimerTasks, automatically starting
* the Timer on initialization and cancelling it on destruction of the context.
* In scenarios that just require static registration of tasks at startup,
* there is no need to access the Timer instance itself in application code.
*
* <p>Note that Timer uses a TimerTask instance that is shared between
* repeated executions, in contrast to Quartz which instantiates a new
* Job for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see ScheduledTimerTask
* @see java.util.Timer
* @see java.util.TimerTask
*/
public class TimerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private ScheduledTimerTask[] scheduledTimerTasks;
private boolean daemon = false;
private Timer timer;
/**
* Register a list of ScheduledTimerTask objects with the Timer that
* this FactoryBean creates. Depending on each SchedulerTimerTask's
* settings, it will be registered via one of Timer's schedule methods.
* @see java.util.Timer#schedule(java.util.TimerTask, long)
* @see java.util.Timer#schedule(java.util.TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long)
*/
public void setScheduledTimerTasks(ScheduledTimerTask[] scheduledTimerTasks) {
this.scheduledTimerTasks = scheduledTimerTasks;
}
/**
* Set whether the timer should use a daemon thread,
* just executing as long as the application itself is running.
* <p>Default is "false": The timer will automatically get cancelled on
* destruction of this FactoryBean. Hence, if the application shuts down,
* tasks will by default finish their execution. Specify "true" for eager
* shutdown of threads that execute tasks.
* @see java.util.Timer#Timer(boolean)
*/
public void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public void afterPropertiesSet() {
logger.info("Initializing Timer");
this.timer = createTimer(this.daemon);
// Register all ScheduledTimerTasks.
if (this.scheduledTimerTasks != null) {
for (int i = 0; i < this.scheduledTimerTasks.length; i++) {
ScheduledTimerTask scheduledTask = this.scheduledTimerTasks[i];
if (scheduledTask.getPeriod() > 0) {
// repeated task execution
if (scheduledTask.isFixedRate()) {
this.timer.scheduleAtFixedRate(
scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
else {
this.timer.schedule(
scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
}
else {
// One-time task execution.
this.timer.schedule(scheduledTask.getTimerTask(), scheduledTask.getDelay());
}
}
}
}
/**
* Create a new Timer instance. Called by <code>afterPropertiesSet</code>.
* Can be overridden in subclasses to provide custom Timer subclasses.
* @param daemon whether to create a Timer that runs as daemon thread
* @return a new Timer instance
* @see #afterPropertiesSet()
* @see java.util.Timer#Timer(boolean)
*/
protected Timer createTimer(boolean daemon) {
return new Timer(daemon);
}
public Object getObject() {
return this.timer;
}
public Class getObjectType() {
return Timer.class;
}
public boolean isSingleton() {
return true;
}
/**
* Cancel the Timer on bean factory shutdown, stopping all scheduled tasks.
* @see java.util.Timer#cancel()
*/
public void destroy() {
logger.info("Cancelling Timer");
this.timer.cancel();
}
}
这个类就是运行我们任务的类了,我们可以定制N个任务,只需要塞到这里就ok了
相关文章推荐
- Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解
- JAVA中 Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- spring 定时器两种实现方式
- Spring定时器的两种实现方式二(quartz)
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- 两种方式实现java定时器,使用quartz定时器框架和java自带Timer定时器,编写定时任务
- spring两种定时器实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- JAVA中 Spring定时器的两种实现方式
- 基于Maven的SpringBoot项目实现热部署的两种方式
- 模拟spring,Aop(JDK与CGLib两种方式实现)
- Spring系列之 (六):Spring实现IOC的两种方式(XML和注解)