笔记源码连接:Spring.html(imocc上的排版和html不同,建议看云盘里的源码,自己看完是视频总结的笔记)
Spring
Annotation
前4行被称为元注解
@Target({ElementType.METHOD,ElementType.TYPE}) 作用域,CONSTRUCTOR(构造方法声明),FIELD(字段声明),LOCAL_VARIABLE(局部变量声明),METHOD(方法声明)PACKAGE(包声明),PARAMETER(参数声明),TYPE(类,接口)
@Retention(RetentionPolicy.RUNTIME) 生命周期,SOURCE(只在源码显示,编译时会丢弃),CLASS(编译时会记录到class中,运行时忽略)RUNTIME(运行时存在,可通过反射读取)
@Inherited 允许子类继承
@Documented 生成javadoc时会包含注解
public @Interface Description{ 使用@interface关键字定义注解,成员的类型是受限制的,合法的类型包括原始类型及String,Class,Annotation,Enumeration
String desc(); 成员以无参无异常方式声明,如果注解只有一个成员,则成员名必须取名为Value(),在使用时可以忽略成员名和赋值号(=)
String authot(); 注解可以没有成员,没有成员的注解被称为标识注解
int age() default 18; 可以使用default为成员指定一个默认值
}
Aware
Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean初始化后,可以获得相应的次元,通过Aware接口,可以对Spring相应的资源进行操作
Resource
针对于资源文件统一接口
classpath : (classpath:com/myapp/config.xml)
file : (file:/data/config.xml)
http, : (http://myserver/logo.png)
(none) : (/data/config.xml)
@Component,@Repository,@Service,@Controller
@Scope
@Bean
@Required
@Autowired
@Autowired适用于fields(字段), constructors(构造器), multi-argumentmethods(多参数方法)这些情况下允许在参数级别使用@Qualifier注解缩小范围的情况
@Order
@Qualifier
@Resource
注解提供的名字被解析为一个bean的名称,这是由ApplicationContext的中的CommonAnnotationBeanPostProcessor发现并处理的
@Bean
Bean的作用域包括singleton, prototype, request, session, global
@Configuration
@ImportResource,@Value
@Configuration
@ImportResource("classpath:/com/acme/properties-config.xml")
publiuc 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="com.acme.AppConfig"/>
<bean class="org.springframeword.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</beans>
@PostConstruct,@PreDestroy
@Inject等效于@Autowired,可以使用于类,属性,方法,构造器
@Named
@Named与@Component是等效的,和@Qualifier相似
@EnableAspectJAutoProxy
@Configuration
@EnableAspectJAutoProxy //自动使用AspectJ进行代理
public class AppConfig{
}
等于
<aop:aspectj-autoproxy/>
@Aspect
一个类中的@Aspect注解标识它为一个切面,并且将自己从自动代理类中排除
@Pointcut
private void anyOldTransfer(){
}
组合pointcut
切入点表达式可以通过 (&& , , != )进行组合,可以以通过名字引入切入点表达式
@Pointcut("execution(public * (..))")
private void anyPublicOperation(){
}
@Pointcut("within(com.xyz.someapp.trading..)")
private void inTrading(){
}
@Pointcut("anyPublicOperation() && inTrading")
private void trading(){
}
Supported Pointcut Designators
Before advice
@Component
@Aspect
public class MoocAspect{
@Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
public void before(){
}
}
@AfterReturning
After returning advice
@Aspect
public class AfterReturningExample{
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck(){
}
}
有时候需要在通知体内得到返回的实际值,可以使用@AfterReturning绑定返回值的形式
@Aspect
public class AfterReturningExample{
@AfterReturning(
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning = "retVal")
public void doAccessCheck(Object retVal){
}
}
@AfterThrowing
After throwing advice
@Aspect
public class AfterThrowingExample{
@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doRecoveryActions(){
}
}
有时候需要在通知体内得到返回的实际值,可以使用@AfterReturning绑定返回值的形式
@Aspect
public class AfterThrowingExample{
@AfterThrowing(
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing = "ex")
public void doRecoveryActions(DataAccessException ex){
}
}
@After
After (finally) advice
@Aspect
public class AfterFinallyExample{
@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doReleaseLock(){
}
}
Around advice
@Aspect
public class AroundExample{
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
Object retVal = pjp.proceed();
return retVal;
}
}
Advice
Advice传递参数
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation && args(account,..)")
private void validateAccount(Account account){
}
这里的方法Account参数可以是任何类的对象,常用于获取相应的参数,做一些判断,或者日志记录
@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation && args(account,..)")
private void accountDataAccessOperatior(Account account){
}
@Before("accountDataAccessOperatior(account)")
public void calidateAccount(Account account){
}
作为一种记录,只是记录这个注解应用的一些方法
Advice的参数及泛型
Spring AOP 可以处理泛型类的声明和使用方法的参数
public interface Sample{
void sampleGenericMethod(T param);
void sampleGenericCollectionMethod(Collection param);
}
@before("execution( ..Sample+.sampleGenericMethod()) && args(param)")
public void beforeSampleMethod(MyType param){
}
@before("execution( ..Sample+.sampleGenericCollectionMethod()) && args(param)")
public void beforeSampleMethod(Collection param){
}
Advice参数名称
通知和切入点注解有一个额外的"argNames"属性,它可以用来指定所有的方法的参数
@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable)
public void audit(Object bean ,Auditable auditable){
AuditCode code = auditable.value();
}
如果第一个参数是JoinPoint,ProceedingJoinPoint,JoinPoint.StaticPart,那么可以忽略它
@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable)
public void audit(,JoinPoint jp ,Object bean ,Auditable auditable){
AuditCode code = auditable.value();
}
Introductions
例如:给定一个接口UsageTracked,并且该接口拥有DefaultUsageTracked的实现,接下来的切面声明了所有的service接口的实现都实现了UsageTracked接口
@Aspect
public class UsageTracking{
@DeclareParents(value="com.xyz.myapp.service.*+",defaultImpl=DefaultUsageTracked.class)
public static UsageTracked mixin;
@Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)")
public void recordUsage(UsageTracked usageTracked){
usageTracked.incrementUseCount();
}
}
切面实例化模型
service对象的每个方法在第一次执行的时候创建切面实例,切面在service对象失效的同时失效
@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect{
private int someState;
@Before(com.xyz.myapp.SystemArchitecture.businessService())
public void recordServiceUsage(){
}
}
2025 - 快车库 - 我的知识库 重庆启连科技有限公司 渝ICP备16002641号-10
企客连连 表单助手 企服开发 榜单123