Spring-IOC、AOP
结构:
HelloWorld.java:
package com.spring.test.helloWorld; public interface HelloWorld { public void sayHello(); }
HelloWorldService.java:
package com.spring.test.helloWorld; public class HelloWorldService { private HelloWorld helloWorld; public HelloWorldService() { } public void setHelloWorld(HelloWorld helloWorld) { this.helloWorld = helloWorld; } public HelloWorld getHelloWorld() { return this.helloWorld; } }
SpringHelloWorld.java:
package com.spring.test.helloWorld.impl; import com.spring.test.helloWorld.HelloWorld; public class SpringHelloWorld implements HelloWorld { @Override public void sayHello() { System.out.println("Spring Say Hello!!"); } }
StrutsHelloWorld.java:
package com.spring.test.helloWorld.impl; import com.spring.test.helloWorld.HelloWorld; public class StrutsHelloWorld implements HelloWorld { @Override public void sayHello() { System.out.println("Struts Say Hello!!"); } }
beans.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="springHelloWorld" class="com.spring.test.helloWorld.impl.SpringHelloWorld"></bean> <bean id="strutsHelloWorld" class="com.spring.test.helloWorld.impl.StrutsHelloWorld"></bean> <bean id="helloWorldService" class="com.spring.test.helloWorld.HelloWorldService"> <property name="helloWorld" ref="springHelloWorld"/> </bean> </beans>
pom.xml
<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>com.spring</groupId> <artifactId>Spring</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- Spring Core --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version> </dependency> <!-- Spring Context --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> </dependency> </dependencies> </project>
HelloProgram.java:
package com.spring.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.test.helloWorld.HelloWorld; import com.spring.test.helloWorld.HelloWorldService; public class HelloProgram { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//读取beans.xml 文件来创建一个应用程序上下文对象 HelloWorldService service = (HelloWorldService) context.getBean("helloWorldService"); HelloWorld hw= service.getHelloWorld(); hw.sayHello(); } }
运行HelloProgram.java
修改beans.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="springHelloWorld" class="com.spring.test.helloWorld.impl.SpringHelloWorld"></bean> <bean id="strutsHelloWorld" class="com.spring.test.helloWorld.impl.StrutsHelloWorld"></bean> <bean id="helloWorldService" class="com.spring.test.helloWorld.HelloWorldService"> <property name="helloWorld" ref="strutsHelloWorld"/><!-- IoC容器创建strutsHelloWorld对象并通过setter方法注入依赖 --> </bean> </beans>
运行HelloProgram.java:
-----------------------------------------------------------------------------
public class AaaServiceImpl extends AbstractxxxService {
}
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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd" default-lazy-init="true"> <!-- 任务定时器 --> <task:scheduler id="threadPoolTaskScheduler" pool-size="10" /> <!--queue-capacity:队列容量;rejection-policy指定执行器队列满时的执行策略 1)ABORT(默认):直接抛出; 2)CALLER_RUNS:不会将任务交给执行器线程,而是让调用者线程来执行该任务; 3)DISCARD_OLDEST:丢弃老的政策; 4)DISCARD:丢弃政策 --> <task:executor id="threadPoolTaskExecutor" pool-size="10" queue-capacity="10" /> <task:scheduled-tasks scheduler="threadPoolTaskScheduler"> <task:scheduled ref="aaaService" method="run" cron="0/1 * * * * ?" /> </task:scheduled-tasks> <!-- 父类 --> <bean id="autoCoreService" class="com.dscomm.remark.core.task.AbstractxxxService"> <property name="xxxOperateService" ref="xxxOperateService" /> <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" /> </bean> <!-- 子类 --> <bean id="aaaService" class="com.dscomm.remark.regular.coc.execute.AaaServiceImpl"> <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" /> </bean> </beans>
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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd" default-lazy-init="true"> <!-- 任务定时器 --> <task:scheduler id="threadPoolTaskScheduler" pool-size="10" /> <!--queue-capacity:队列容量;rejection-policy指定执行器队列满时的执行策略 1)ABORT(默认):直接抛出; 2)CALLER_RUNS:不会将任务交给执行器线程,而是让调用者线程来执行该任务; 3)DISCARD_OLDEST:丢弃老的政策; 4)DISCARD:丢弃政策 --> <task:executor id="threadPoolTaskExecutor" pool-size="10" queue-capacity="10" /> <task:scheduled-tasks scheduler="threadPoolTaskScheduler"> <task:scheduled ref="aaaService" method="run" cron="0/1 * * * * ?" /> </task:scheduled-tasks> <!-- 父类 --> <bean id="autoCoreService" class="com.dscomm.remark.core.task.AbstractxxxService" abstract="true"> <property name="xxxOperateService" ref="xxxOperateService" /> <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" /> </bean> <!-- 子类 --> <bean id="aaaService" class="com.dscomm.remark.regular.coc.execute.AaaServiceImpl" parent="autoCoreService"> </bean> </beans>
子类只需要配置 parent="父类的bean ID" ,这样,父类注入的属性,子类就不用再注入了,就可以直接父类的属性了。
-----------------------------------------------------------------------------
spring AOP
-----------------------------------------------------------------------------
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="get*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* org.mx..dao.I*Dao.*(..))" id="daoMethods" /> <aop:pointcut expression="execution(* org.mx..task.I*Task.*(..))" id="taskMethods" /> <aop:pointcut expression="execution(* com.business..I*Business.*(..))" id="businessMethods" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="taskMethods" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="businessMethods" /> <aop:aspect id="LogAspect" ref="LogAspectBean"> <aop:pointcut expression="execution(* org.mx..task.I*Task.*(..))" id="logsPointCut" /> <aop:pointcut expression="execution(* com.business.I*Business.*(..))" id="logsPointCutBusiness" /> <aop:around pointcut-ref="logsPointCut" method="businessLogAround" /> <aop:around pointcut-ref="logsPointCutBusiness" method="businessLogAround" /> </aop:aspect> </aop:config> </beans>
什么是spring AOP
答:
1.切面(Aspect):就是完成额外任务的类
2.连接点(Joinpoint):就是调用的目标方法
3.通知(Advice):切面中的方法
4.切入点(Pointcut):匹配连接点的断言。(执行通知的 if,就是一个匹配规则)
AOP的实现原理
答:
当获取对象时,首先将对象与切入点表达式进行匹配。如果匹配成功,
则会创建代理对象。然后代理对象执行方法时就会执行通知。
Spring bean的生命周期
1.首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化,
2.按照Bean定义信息配置信息,注入所有的属性,
3.如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id,
4.如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory,
5.如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext,
6.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法,
7.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,
8.如果Bean配置了init-method方法,则会执行init-method配置的方法,
9.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,
10.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了
11.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,
12.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束