spring入門——慕課網
IOC:控制反轉(Inversion of Control)
DI:依賴注入(Dependency Injection)
邊看邊編寫的程式碼:
http://download.csdn.net/detail/fulq1234/9754355
**2-1:IOC及Bean容器**
1.IOC是介面程式設計
2.介面:OneInterface
實現類:OneInterfaceImpl
spring-ioc.xml:
<bean id="oneInterface" class="com.imooc.ioc.interfaces.OneInterfaceImpl"></bean>
測試類:
OneInterface temp=(OneInterface)ac.getBean("oneInterface");
3.Bean容器初始化
檔案
FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("F:/workspace/appcontext.xml");
//classpath
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring-context.xml");
Web應用
<web-app> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-start>1</load-on-start> </servlet> </web-app>
**2-2:Spring注入方式**
1.設值注入:自動呼叫類的set方法
<beans> <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl"> <property name="injectionDAO" ref="injectionDAO"/> </bean> <bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"/> </beans>
構造注入:必須有個構造器,構造器的引數是InjectionDAO
<bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"/>
</bean>
**3-1:Spring Bean裝配之Bean的配置項及作用域**
1.Bean配置項
Id
Class
Scope
Constructor arguments
Properties
Autowiring mode
lazy-initialization mode
Initialization/destruction method
Bean的作用域(scope)
singleton:單例,指一個Bean容器中只存在一份,預設使用
prototype:每次請求(每次使用)建立新的,destroy方式不生效
request:每次http請求建立一個例項且僅在當前request內有效
session:同上,每次http請求建立,當前session內有效
global session:基於portlet的web中有效(portlet定義了global session),如果是在web中,同session
**3-2:spring Bean裝配之Bean的生命週期**
1.生命週期
定義
初始化
使用
銷燬
在網上一個比較好的圖片,引用一下
實現org.springframework.beans.factory.InitializingBean介面,覆蓋afterPropertiesSet方法
配置init-method
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class Examplebean{
public void init(){}
}
實現org.springframework.beans.factory.DisposableBean介面,覆蓋destroy方法
配置destroy-method
4.配置全域性預設初始化.銷燬方法
<?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"
default-init-method="init" default-destory-method="destroy">
</beans>
**3-3.Spring Bean裝配之Aware介面**
1.ApplicationContextAware
BeanNameAware
Java檔案
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class MoocbeanName implements BeanNameAware,ApplicationContextAware{
private String name;
public void setBeanName(String arg0) {
name=arg0;
System.out.println("MoocbeanName:"+arg0);
}
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
System.out.println("MoocbeanName:"+arg0.getBean(name).hashCode());
}
}
spring-aware.xml
<bean id="moocbeanName" class="com.imooc.aware.MoocbeanName"/>
測試
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-aware.xml"})
public class MoocApplicationContextTest {
@Autowired
ApplicationContext ac;
@Test
public void testBeanname(){
System.out.println("testBeanname:"+ac.getBean("moocbeanName").hashCode());
}
}
列印:
MoocbeanName:moocbeanName
MoocbeanName:1607305514
testBeanname:1607305514
**3-4.Spring Bean裝配之自動裝配(Autowiring)**
No:不做任何操作
byname:根據屬性名自動裝配
byType:型別,如果沒有找到相匹配的bean,則什麼事都不發生
Constructor:與byType方式類似,不同之處在於它應用與構造器引數。如果沒有找到,那麼就丟擲異常
正常的是以“設值注入”和“構造注入”,現在不用寫這個,用自動裝配
<beans ..... default-autowire="byName">
</beans>
**3-5.Spring Bean裝配之Resource**
1.針對於資原始檔的統一介面
- UrlResource : URL對應的資源,根據一個URL地址即可構建
- ClassPathResource : 獲取類路徑下的資原始檔
- FileSystemResource : 獲取檔案系統裡面的資源
- ServletContextResource : ServletContext封裝的資源,用於訪問ServletContext環境下的資源
- InputStreamResource : 針對於輸入流封裝的資源
- ByteArrayResource : 針對於位元組陣列封裝的資源
2.ResourceLoader
所有Application contexts都包含介面ResourceLoader
public interface ResourceLoader{
Resource getResource(String location);
}
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");//依賴於Application context
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("file:/some/resource/path/myTemplate.txt");
public class MoocResource implements ApplicationContextAware{
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
this.applicationContext=arg0;
}
public void resource() throws IOException{
//Resource resource = applicationContext.getResource("classpath:config.txt");
//Resource resource = applicationContext.getResource("file:F:\\eclipse-jee-mars-2-win32-x86_64\\eclipse\\workspace\\Spring\\src\\main\\resources\\config.txt");
//Resource resource = applicationContext.getResource("url:http://www.w3school.com.cn/xml/xml_syntax.asp");
Resource resource = applicationContext.getResource("config.txt");//依賴於Application context,也就是classpath
System.out.println("file:"+resource.getFilename());
System.out.println("length:"+resource.contentLength());
}
}
**4-1.Spring Bean裝配之Bean的定義及作用域的註解實現**
1.<context:annotation-config/>:僅會查詢在同一個AppliationContext中的Bean註解
@Component,@Repository,@Service,@Controller
@Required
@Autowired
@Qualifier
@Resource
<context:component-scan>包含<context:annotation-config>,通常在使用前者後,不再使用後者
2.預設情況下,類被自動發現並註冊bean的條件是:使用@Component,@Repository,@Service,@Controller註解或者使用@Component的自定義註解
如:下面例子的XML配置忽略所有的@Repository註解並用“Stub”代替
<beans>
<context:component-scan base-package="org.example">
<context:include-filter type="regex" expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>
type包含:annotation,assignable,aspectj,regex,custom
3.還可以使用use-default-filters="false"禁用自動發現與註冊
4,定義Bean
. @Service("myMovieListener")
. 可以自定義bean的命令策略
<beans>
<context:component-scan base-package="org.example" name-generator="org.example.MyNameGenerator"/>
</beans>
5,作用域(Scope)
@Scope("prototype")
也可以自定義scope策略,實現ScopeMetadataResolver介面並提供一個無參構造器
<beans>
<context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
</beans>
6,代理方式
可以使用scoped-proxy屬性指定代理,有三個值可選:no,interfaces,targetClass
<beans>
<context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
</beans>
**4-2.Spring Bean裝配之Autowired註解說明-1**
[email protected]註解試用於bean屬性的setter方法。
受影響的bean(MovieFinder)屬性必須在配置時被填充,
public class SimpleListerner{
private MovieFinder m;
@Required
public void setMovieFinder(MovieFinder m){
thism=m;
}
}
[email protected]
可以setter方法
private MovieFinder m;
@Autowired
public void setMovieFinder(MovieFinder m){
this.m=m;
}
可用於構造器或者成員變數
@Autowired
private MovieCatelog movieCatelog;
private CustomerPDao cDao;
@Autowired
public MovieRecommender(CustomerPDao cDao){
this.cDao=cDao;
}
@Autowired(required=false)
每個類只能有一個構造器被標記為required=true
**4-3.Spring Bean裝配之Autowired註解說明-2**
1.可以使用@Autowired註解那些眾所周知的解析依賴性介面,比如:BeanFactory,ApplicationContext context,Enviroment,ResourceLoader,ApplicationEventPublisher,
@Autowired是由Spring BeanPostProcessor處理的,所以不能在自己的BeanPostProcessor或BeanFacotryPostProcessor型別應用這些註解,這些型別必須通過xml或者spring的@Bean註解
.可以通過添加註解給需要該型別的陣列的欄位或方法,以提供ApplicationContext中的所有特定型別的bean
private Set<MovieCatelog> m;
@Autowired
public void setMovieCatelogs(Set<MovieCatelog> m){
this.m=m;
}
.可以用於裝配key為String的Map
.如果希望陣列有序,可以讓bean實現org.springframework.core.Ordered介面或使用的@Order註解
@Order(2)
@Component
public class BeanImplOne implements BeanInterface {
}
@Order(1)
@Component
public class BeanImplTwo implements BeanInterface {
}
@Component
public class BeanInvoker {
@Autowired
private List<BeanInterface> list;
@Autowired
private Map<String,BeanInterface> map;
public void say(){
if(null != list){
System.out.println("list...");
for(BeanInterface bean : list){
System.out.println(bean.getClass().getName());
}
}else{
System.out.println("List is null!!!");
}
if(null!=map && 0!=map.size()){
System.out.println("map....");
for(Map.Entry<String, BeanInterface> entry:map.entrySet()){
System.out.println(entry.getKey()+" "+entry.getValue().getClass().getName());
}
}else{
System.out.println("map is null!!!!");
}
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-beanannotation.xml"})
public class BeanInvokerTest {
@Autowired
ApplicationContext ac;
@Test
public void testMultiBean() {
BeanInvoker invoker=(BeanInvoker) ac.getBean("beanInvoker");
invoker.say();
}
}
列印結果:
list...
com.imooc.beanannotation.multibean.BeanImplTwo
com.imooc.beanannotation.multibean.BeanImplOne
map....
beanImplOne com.imooc.beanannotation.multibean.BeanImplOne
beanImplTwo com.imooc.beanannotation.multibean.BeanImplTwo
**4-4.Spring Bean裝配之Autowired註解說明-3**
@Qualifier
按型別自動裝配可能多個bean例項的情況,可以使用Spring的@Qualifier註解縮小範圍(或指定唯一),也可以用於指定單獨的構造器引數或方法引數
1.
public class MovieRe{
@Autowired
@Qualifier("main")
private MovieCatalog movieCatelog;
//...
}
public class MovieRe{
private MovieCatalog movicCatelog;
@Autowired
public void prepare(@Qualifier("main") MovieCatelog movieCatelog){
this.movieCatelog=movieCatelog;
}
//...
}
2.
<beans>
<bean class="example.SimpleMovieCatelog">
<qualifier value="main"/>
</bean>
<bean class="example.SimpleMovieCatelog">
<qualifier name="action"/>
</bean>
</beans>
如果通過名字進行註解注入,主要使用的不是@Autowired(即使在技術上能夠通過@Qualifier指定bean的名字)@Resource
[email protected]適用於fields,constructors,multi-argument methods這些允許在引數級別使用@Qualifier註解縮小範圍的情況
@Resource適用於成員變數,只有一個引數的setter方法,所以在目標是構造器或一個多引數方法時,最好的方式是使用qualifiers
**4-5 spring Bean裝配之基於Java的容器註解說明——@Bean**
[email protected]標識一個用於配置和初始化一個由SpringIoC容器管理的新物件的方法,類似於XML配置檔案的<bean/>
.可以在Spring的@Component註解的類中使用@Bean註解(僅僅是可以)。
.上一點中,通常使用的是@Configuration
@Configuration
public class AppConfig{
@Bean
public MyService myService(){
return new MyServiceImpl();
}
}
等價於
<beans>
<bean id="myS" class="com.acme.services.MyServiceImpl"/>
</beans>
**4-6 spring Bean裝配之基於Java的容器註解說明——@ImportResource和@Value**
@Configuration
@ImportResource("classpath:/com/acme/jdbc.properties");
public class AppConfig{
@Value("${jdbc.url}"
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
return new DriverManagerDataSource(url,username,password);
}
}
等價於
<beans>
<context:annotation-config/>
<context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
<!--其作用是載入資原始檔-->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
**4-7 spring Bean裝配之基於Java的容器註解說明——@Bean和@Scope**
預設@Bean是單例的
@Bean
@Scope(value="session",proxyMode=ScopedProxyMode.TARGET_class)
**4-8 spring Bean裝配之基於Java的容器註解說明——基於泛型的自動裝配**
@Configuration
public class MyConfiguration{
@Bean
public StringStore stringStore(){
return new StringStore();
}
@Bean
public IntegerStore integerStore(){
return new IntegerStore();
}
}
使用1
@Autowired
private Store<String> s1;
@Autowired
private Store<Integer> s2;
使用2
@Autowired
private List<Store<Integer>> s;
**4-9. Spring Bean裝配之Spring對JSR支援的說明**
@Resource
@Named 使用特定名稱進行依賴注入,於@Component是等效的
@Injected
**5-1. Spring AOP基本概念及特點**
AOP:Aspect Oriented Programming的縮寫
通過預編譯和執行期動態代理實現程式功能的統一維護的一種技術。
預編譯
AspectJ
執行期動態代理(JDK動態代理,CGLib動態代理)
SpringAOP JbossAOP
AOP的幾個相關概念
切面(Aspect):
連線點(Joinpoint)
通知(Advice):在特定連線點執行的動作
切入點(Pointcut)
引入(Introduction)
目標物件(Target Object)
AOP代理(AOP Proxy)
織入(Weaving)
Advice的型別
前置通知(Before advice)
返回後通知(After returning advice)
丟擲異常後通知(After throwing advice)
後通知(After(finally) advice)
環繞通知(Around Advice)
**5-2. 配置切面aspect**
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
...
</aop>
</aop:config>
**5-3. 配置切入點Pointcut**
pointcut
. execution(public **(..)) 切入點為執行所有public方法時
. execution(* set*(..)) 切入點為執行所有set開始的方法時
. execution(* com.xyz.service.AccountService.*(..) 切入點為執行AccountService類中的所有方法時
. execution(* com.xyz.service..(..)) 切入點為執行com.xyz.service包下的所有方法時
. execution(* com.xyz.service...(..)) 切入點為執行com.xyz.service包及其子包下的所有方法時
. within(com.xyz.service.*)(only in Spring AOP)
. within(com.xyz.service..*(only in Spring AOP) within 用於匹配指定型別內的方法執行
. this(com.xyz.service.AccountService)(only in Spring AOP) this 用於匹配當前AOP代理物件型別的執行方法。
. target(com.xyz.service.AccountService)(only in Spring AOP) target用於匹配當前目標物件型別的執行方法
. args(java.io.Serializable)(only in Spring AOP)
. @Target(org.springframework.tansaction.annotation.Transactional)(only in Spring AOP)
. @within(org.springframework.tansaction.annotation.Transactional)(only in Spring AOP)
. @annotation(org.springframework.tansaction.annotation.Transactional)(only in Spring AOP)
args用於匹配當前執行的方法傳入的引數為指定型別的執行方法。
pointcut
. @args(com.xyz.security.Classified)(only in Spring AOP)
. bean(tradeService)(only in Spring AOP)
. bean(*Service)(only in Spring AOP)
**5-4. Advice應用(上)**
<beans>
<bean id="moocAspect" class="com.imooc.aop.schema.advice.MoocAspect"></bean>
<bean id="aspectBiz" class="com.imooc.aop.schema.advice.biz.AspectBiz"></bean>
<aop:config>
<aop:aspect id="moocAspectAOP" ref="moocAspect">
<aop:pointcut expression="execution(* com.imooc.aop.schema.advice.biz.AspectBiz.*(..))" id="moocPointcut"/>
<aop:before method = "before" pointcut-ref = "moocPointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref = "moocPointcut"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="moocPointcut"/>
<aop:after method="after" pointcut-ref="moocPointcut"/>
<aop:around method="around" pointcut-ref="moocPointcut"/>
<aop:around method="aroundInit" pointcut="execution(* com.imooc.aop.schema.advice.biz.AspectBiz.init(String,int))
and args(bizName,times)"/>
</aop:aspect>
</aop:config>
</beans>
public Object around(ProceedingJoinPoint pjp){
//start stopwatch
Object retVal = pjp.proceed();
//stop stopwatch
return retVal;
}
public Object aroundInit(ProceedingJoinPoint pjj,String bizName,int times) throws Throwable{
System.out.println("MoocAspect aroundInit bizName:"+bizName+",times:"+times);
//Start
Object obj= pjj.proceed();
//Stop
return obj;
}
應用舉例,記錄日誌。當執行action類的時候,會記錄日誌
package com.company.business.admin.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.company.business.admin.core.service.IAdminLogManager;
import com.company.common.bean.core.AdminUser;
import com.company.core.util.DateUtil;
/**
* 此切面主要用於切所有action類的所有方法<br/>
* 只要action執行任何方法就會觸發該切面
* @since 2016-12-6 16:50
*/
@Component
@Aspect
public class AdminAspect {
@Autowired
private IAdminLogManager adminLogManager;
private Log log = LogFactory.getLog(AdminAspect.class);
@Pointcut("execution (public * com.company.business.admin.dev.*.action.*Controller.*(..))")
public void serviceExecution(){}
@Before("serviceExecution()")
public void startSomething(JoinPoint jp) {
}
@After("serviceExecution()")
public void endSomething(JoinPoint jp) {
AdminUser currUser = UserContext.getCurrentAdminUser();
String username = "未知";
String realname = "未知";
if (currUser != null) {
username = currUser.getUsername();
realname = currUser.getRealname();
}
try {
String methodname = jp.getSignature().getName();
if (!methodname.toLowerCase().contains("list") && !methodname.toLowerCase().contains("show")) {
adminLogManager.add(new AdminLog(username,
realname, //真實姓名
jp.getTarget().getClass().getName(), //操作人操作的controller類
jp.getSignature().getName(), //操作人操作的controller類的方法名
DateUtil.getDateline()//操作時間
));
}
} catch (Exception e) {
log.error("切面插日誌異常:" + e.getMessage() ,e);
}
}
}
**5-6. Introductions應用**
. schema-defined aspects只支援singleton model
<beans>
<bean id="moocAspect" class="com.imooc.aop.schema.advice.MoocAspect"></bean>
<bean id="aspectBiz" class="com.imooc.aop.schema.advice.biz.AspectBiz"></bean>
<aop:config>
<aop:aspect id="moocAspectAOP" ref="moocAspect">
<aop:declare-parents types-matching="com.imooc.aop.schema.advice.biz.*(+)" implement-interface="com.imooc.aop.schema.advice.Fit" default-impl="com.imooc.aop.schema.advice.FitImpl"/>
</aop:aspect>
</aop:config>
</beans>
Fit.java
package com.imooc.aop.schema.advice;
public interface Fit {
void filter();
}
FitImpl.java
package com.imooc.aop.schema.advice;
public class FitImpl implements Fit {
public void filter() {
System.out.println("FitImpl filter.");
}
}
MoocAspect.java
package com.imooc.aop.schema.advice;
import org.aspectj.lang.ProceedingJoinPoint;
public class MoocAspect {
public void before() {
System.out.println("MoocAspect before.");
}
public void afterReturning() {
System.out.println("MoocAspect afterReturning.");
}
public void afterThrowing() {
System.out.println("MoocAspect afterThrowing.");
}
public void after() {
System.out.println("MoocAspect after.");
}
public Object around(ProceedingJoinPoint pjp) {
Object obj = null;
try {
System.out.println("MoocAspect around 1.");
obj = pjp.proceed();
System.out.println("MoocAspect around 2.");
} catch (Throwable e) {
e.printStackTrace();
}
return obj;
}
public Object aroundInit(ProceedingJoinPoint pjp, String bizName, int times) {
System.out.println(bizName + " " + times);
Object obj = null;
try {
System.out.println("MoocAspect aroundInit 1.");
obj = pjp.proceed();
System.out.println("MoocAspect aroundInit 2.");
} catch (Throwable e) {
e.printStackTrace();
}
return obj;
}
}
AspectBiz.java
package com.imooc.aop.schema.advice.biz;
public class AspectBiz {
public void biz() {
System.out.println("AspectBiz biz.");
// throw new RuntimeException();
}
public void init(String bizName, int times) {
System.out.println("AspectBiz init : " + bizName + " " + times);
}
}
test
package com.imooc.aop.schema.advice.biz;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.imooc.aop.schema.advice.Fit;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-aop-schema-advice2.xml"})
public class AspectBizTest2 {
@Autowired
ApplicationContext ac;
@Test
public void testFit() {
Fit biz=(Fit)ac.getBean("aspectBiz");
biz.filter();
}
}
輸出結果
FitImpl filter.
**5-7. Advisors**
<beans>
<aop:config>
<aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service..(..))"/>
<aop:advisor pointcut-ref="businessService" advice-ref="tx-advice"/>
</aop:config>
<tx:advice id="tx-advice">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
</beans>
**6-1. Spring AOP API的Pointcut,advice概念及應用**
. NameMatchMethodPointcut根據方法名字進行匹配
. 成員變數:mappedNames,匹配的方法名集合
BeforeAdvice
ThrowsAdvice
AfterReturningAdvice
Interceptor
MethodInterceptor implements Interceptor
引入通知(Introduction advice)作為一個特殊的攔截通知,需要IntroductionAdvisor和IntroductionInterceptore僅適用於類,不能和任何切入點一起使用。
**6-2. ProxyFactoryBean及相關內容(上)**
<?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"
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">
<bean id="bizLogicImplTarget" class="com.imooc.aop.api.BizLogicImpl"/>
<bean id="moocBeforeAdvice" class="com.imooc.aop.api.MoocBeforeAdvice"/>
<bean id="moocAfterReturningAdvice" class="com.imooc.aop.api.MoocAfterReturningAdvice"/>
<bean id="moocThrowsAdvice" class="com.imooc.aop.api.MoocThrowsAdvice"/>
<bean id="moocMethodInterceptor" class="com.imooc.aop.api.MoocMethodInterceptor"/>
<bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames">
<list>
<value>sa*</value>
</list>
</property>
</bean>
<bean id="defaultAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="moocBeforeAdvice"/>
<property name="pointcut" ref="pointcutBean"/>
</bean>
<!-- <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="bizLogicImplTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>defaultAdvisor</value>
<value>moocBeforeAdvice</value>
<value>moocAfterReturningAdvice</value>
<value>moocThrowsAdvice</value>
<value>moocMethodInterceptor</value>
</list>
</property>
</bean> -->
<bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.imooc.aop.api.BizLogic</value>
</property>
<property name="target">
<!-- <ref bean="bizLogicImplTarget"/> -->
<bean class="com.imooc.aop.api.BizLogicImpl"/>
</property>
<property name="interceptorNames">
<list>
<value>moocBeforeAdvice</value>
<value>moocAfterReturningAdvice</value>
<value>moocThrowsAdvice</value>
<value>moocMethodInterceptor</value>
</list>
</property>
</bean>
</beans>
package com.imooc.aop.api;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MoocBeforeAdvice implements MethodBeforeAdvice {
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("MoocBeforeAdvice:"+arg0.getName()+" "+arg1.getClass().getName());
}
}
package com.imooc.aop.api;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MoocAfterReturningAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnVal, Method method, Object[] arg2, Object target) throws Throwable {
System.out.println("MoocAfterReturningAdvice:"+method.getName()+" "+target.getClass().getName()+" "+returnVal);
}
}
package com.imooc.aop.api;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MoocThrowsAdvice implements ThrowsAdvice{
public void afterThrowing(Exception ex) throws Throwable{
System.out.println("afterThrowingAdvice afterThrowing 1");
}
public void afterThrowing(Method method,Object[] args,Object target,Exception ex) throws Throwable{
System.out.println("afterThrowingAdvice afterThrowing 2:"+method.getName()+""+target.getClass().getName());
}
}
package com.imooc.aop.api;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MoocMethodInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("MoocMethodInterceptor 1:"+invocation.getMethod().getName()+" "+invocation.getStaticPart().getClass().getName());
Object obj= invocation.proceed();
System.out.println("MoocMethodInterceptor 2:"+invocation.getMethod().getName()+" "+invocation.getStaticPart().getClass().getName());
return obj;
}
}
package com.imooc.aop.api;
public interface BizLogic {
String save();
}
package com.imooc.aop.api;
public class BizLogicImpl implements BizLogic{
public String save() {
System.out.println("BizLogicImpl:BizLogicImpl save.");
return "Logic save.";
}
}
測試類
package com.imooc.aop.api;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-aop-api.xml"})
public class BizLogicImplTest {
@Autowired
ApplicationContext ac;
@Test
public void testAA() {
BizLogic logic=(BizLogic) ac.getBean("bizLogicImpl");
logic.save();
}
}
執行結果
MoocBeforeAdvice:save [Ljava.lang.Object;
MoocMethodInterceptor 1:save java.lang.reflect.Method
BizLogicImpl:BizLogicImpl save.
MoocMethodInterceptor 2:save java.lang.reflect.Method
MoocAfterReturningAdvice:save com.imooc.aop.api.BizLogicImpl Logic save.
**6-3. ProxyFactoryBean及相關內容(下)**
Proxying classes
. 前面的例子,如果沒有Person介面,這種情況下Spring會使用CGLIB代理,而不是JDK動態代理。
. CGLIB(Code Generation Library)代理的工作原理是在執行時生產目標類的子類,Spring配置這個生成的子類委託方法呼叫到原來的目標。
. 用*做通配,匹配所有攔截器(Interceptor而不是Advice)加入通知鏈
<property name="interceptorNames">
<list>
<value>global*</value>
</list>
</property>
簡化的proxy定義
抽象屬性標記父bean定義為抽象的這樣它不能被例項化
<beans>
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="myService" parent="txProxyTemplate">
<property name="target">
<bean class="org.springframework.samples.MySpecialServiceImpl"/>
</property>
<property name="transactionAttributes"><!--此處可以覆蓋txProxyTemplate-->
<props>
<prop key="get*">PROPAGATTION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATTION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</beans>
**7-1. AspectJ介紹及Ponitcut註解應用**
Spring中配置@AspectJ
確保AspectJ的aspectjweaver.jar庫包含在應用程式(版本1.6.8或更高版本)的classpath中
@Configuration
@EnableAspectJAutoProxy
public class AppConfig{}
或者是
<aop:aspectj-autoproxy/>
aspect
@AspectJ切面使用@Aspect註解配置,擁有@Aspect的任何bean將被Spring自動識別並應用
@Aspect註解是不能夠通過類路徑自動檢測發現的,所有需要配合使用@Component註釋或者在xml配置bean
pointcut
一個切入點通過一個普通的方法定義來提供,並且用@Pointcut註釋,方法返回型別必須是void
execution:匹配方法執行的連線點
within:限制匹配特定型別的連線點
this
target
args
@target
@args
@withiin
@annotation
組合pointcut
切入點表示式可以通過&&,||和!進行組合,也可以通過名字引用切入點表示式。
如:@Pointcut("anyPublicOperation() && inTrading()")
**7-2. Advice定義及例項**
@Component
@Aspect
public class MoocAspect{
@Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
public void before(){}
}
//After returning advice
@Aspect
public class AfterReturningExample{
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck(){}
}
或者
@Aspect
public class AfterReturningExample{
@AfterReturning(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",returning="retVal")
public void doaccessCheck(Object retVal){}
}
After throwing advice
@AfterThrowing
After(finally)advice
@After
Around advice
@Around,通知方法的第一個引數必須是ProceedingJoinPoint型別
@Aspect
public class AroundExample{
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
//start stopwatch
Object retVal = pjp.proceed();
//stop stopwatch
return retVal;
}
}
**7-3. Advice擴充套件**
程式碼1.@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account){}
程式碼2.
@Pointcut("com.xyz.myapp.SystemArchitecture.dataaccessOperation() && args(acount,..)")
private void accountDataAccessOperation(Account account){}
@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account){}
程式碼3.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.NETHOD)
public @interface Auditable{
AuditCode value();
}
程式碼4.
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable){
AuditCode code = auditable.value();
//...
}
相關推薦
spring入門——慕課網
慕課網,spring入門篇 IOC:控制反轉(Inversion of Control)DI:依賴注入(Dependency Injection) 邊看邊編寫的程式碼: http://download.csdn.net/detail/fulq1234/9754355 **2
JavaScript入門--慕課網學習筆記
裏的 編寫 .com span 符號 代碼格式 www 空白 body JAVASCRIPT—(慕課網)入門篇 我們來看看如何寫入JS代碼?你只需一步操作,使用<script>標簽在HTML網頁中插入JavaScript代碼。
Spring 學習--慕課網視訊教學
主要是SpringFramework 學習掌握用法:配置 註解 使用場景 用法優劣深入理解:開發帶來的優勢實踐和總結的反覆spring是輕量級的IOC和AOP的容器框架輕量級 大小和開銷的消耗低IOC達到鬆耦合的目的AOP分離應用的業務邏輯與系統級服務(在執行下都要用到的東西
慕課網Java入門第二季6.1 達達租車系統,使用到繼承、重寫、多態、toString函數
ati next println 構造方法 static class days 慕課網 mage 為了方便理解,畫了個UML圖,可以參考一下為了方便理解,畫了個UML圖,可以參考一下 定義Car類型:載人+載貨 public class Car { int id;
慕課網之javascript入門
真的是 right gin 瀏覽器 方式 range 效果 是我 縮小 這是我的第一篇博客,從今天開始會記錄自己學到的東西,希望自己能學到越來越多。 JavaScript輸出:document.write()四種方式: 1.直接輸出雙引號裏的內容 document.writ
spring慕課網
目的 組件 pri 應用 nbsp 企業應用 包含 周期 開發 資源鏈接 http://spring.io/ http://projects.spring.io/spring-framework/ Spring是什麽? Spring是一個開源的輕量級的應用開發框架,氣目
【總結整理】javascript基礎入門學習(慕課網學習)
節點 confirm pro remove prompt 例如 ref 存儲 基礎入門 https://www.imooc.com/learn/36 註意: javascript作為一種腳本語言可以放在html頁面中任何位置,但是瀏覽器解釋html時是按先後順序的,所以前面
01慕課網《vue.js2.5入門》——Vue中的組件
inpu rip del 慕課網 his AC input roo 實例 TodoList功能開發 <body> <div id="root"> <div> <input v-model="inputVal
python資料分析新手入門課程學習——(二)探索分析與視覺化(來源:慕課網)
一,單因子與對比分析視覺化 資料 import pandas as pd df = pd.read_csv('./HR.csv') #檢視前十條資料 df.head(10) 以下為顯示的結果 我們可以看出: 第一個屬性satisf
python資料分析新手入門課程學習——(一)資料獲取(來源:慕課網)
一、資料獲取手段 1.資料倉庫(DW):將所有業務資料經彙總處理構成 1)特點: 全部事實的記錄;部分維
python資料分析新手入門課程學習——概述(來源:慕課網)
一、流程 二、資料分析概述 含義與目標:使用統計分析方法,在資料中提取有用的資訊
慕課網《monggodb入門》總結
1.幾個重要的網站: MongoDB官網:www.mongodb.org MongoDB國內官網站:www.mongoing.com 2.windows安裝配置:https://blog.csdn.net/heshushun/article/details/77776706 3.mo
慕課網實戰課程之基於Spring Boot技術棧部落格系統企業級前後端實戰
慕課網實戰課程專案-基於Spring boot部落格的搭建教程 技術棧 後端: SpringBoot+ElasticSearch+SpringSecurity 前端: Thymeleaf/Bootstrap/jQuery 資料庫:MySQL/MongoD
慕課網學習 - Struts2入門
簡介:Struts2是當前流行的Java Web框架!本門課程首先介紹Strust2的基本概念和發展歷史,然後從一個案例入手,帶領小夥伴們對Struts2有一個全面的瞭解。接著有對Struts2進行了更深入的講解。相信通過本課程的學習,小夥伴們一定能夠有所收穫。 第1章 概述 本章主要介紹課
js之DOM入門(慕課網學習筆記)
DOM簡介 獲得元素 document.getElementById(’’) 1、通過id獲得元素內容 document.getElementsByTagName(’’) 2、通過標籤獲得元素內容 document.getElementsByClassName(’’) 3、通過
視訊-慕課網Python入門
文章目錄 Python簡介 開發準備 Python基礎語法 一、資料型別 1. 整數(正負):十進位制:12,-32,十六進位制0x字首 10(0xa)-10(-0xa)
慕課網-Django入門與實踐-學習筆記
Detect languageAfrikaansAlbanianAmharicArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese
慕課網Spring Boot 2.0深度實踐-初遇Spring Boot 筆記
1、Spring Boot 的角色 基於Spring Framework,同時是Spring Cloud基礎,承上啟下 Spring Framework是一種JavaEE的框架 SpringBoot是一種快速構建Spring的應用
慕課網c語言入門學習筆記
#include<stdio.h> int main()新標準中是int 而非void 一個c程式中只有一個主函式,main是唯一入口 printf(); return 是函式的返回值,函式型別不同,返回值也不同良好規範 1、一個說明或一個語句佔一行,例如:包含
Python筆記-慕課網-《Python入門》
第三章 動態語言:變數本身型別不固定,可以隨時改變。 a = 'ABC' b = a a = 'XYZ' print b 輸出是ABC,而不是XYZ 用\對字串中某個字元進行轉義 print 'Bob said \"I\'