常用注解
扫描指定的包,包括子包:context.scan("net.xdclass.sp");
里面完成初始化操作,核心方法:context.refresh();
bean定义
@Component
通用组件
细分:@Controller
(⽤于web层) @Service
(用于service层) @Repository
(用于dao仓库层)
bean取名
@Component("XXXX")
bean注⼊
类型注⼊@Autowired
名称注⼊@Qualifier
bean生命周期
@PostConstruct
初始化、@PreDestroy
销毁
bean作用范围
@scope
注解
注释举例:
package net.xdclass.sp.service;
import net.xdclass.sp.domain.Video;
import org.springframework.stereotype.Component;
//@Component("自定义名称")
@Component
public class VideoServiceImpl implements VideoService {
public int save(Video video) {
System.out.println("保存video");
return 1;
}
public Video findById(int id) {
System.out.println("根据id找视频");
return new Video();
}
}
主类运行,测试:
package net.xdclass.sp;
import net.xdclass.sp.domain.Video;
import net.xdclass.sp.service.VideoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//扫描指定的包,包括子包
context.scan("net.xdclass.sp");
//里面完成初始化操作,核心方法
context.refresh();
VideoService videoService = (VideoService) context.getBean("videoServiceImpl");
videoService.findById(2);
Video video = (Video) context.getBean("video");
video.init();
}
}
定义第三方bean
@Configuration
标注在类上,相当于把该类作为spring的xml配置⽂件中的<bean>
作⽤:配置spring容器(应用上下文)
@bean
注解:用于告诉⽅法产⽣⼀个Bean对象,然后这个Bean对象交给Spring管理,Spring将会将这个Bean对象放在自己的IOC容器中
注意点:SpringIOC容器管理⼀个或者多个bean,这些bean都需要在@Configuration注解下进行创建
package net.xdclass.sp.config;
import net.xdclass.sp.domain.VideoOrder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class AppConfig {
// 使用@bean注解,表明这个bean交个spring 进行管理
// 如果没有指定名称,默认采用 方法名 + 第一个字母小写 作为bean的名称
@Bean(name = "videoOrderName",initMethod = "init",destroyMethod = "destroy")
@Scope
public VideoOrder videoOrder(){
return new VideoOrder();
}
}
@PropertySource
,指定加载配置文件(config.properties),配置文件映射到实体类,使用@Value
映射到具体的java属性
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource(value = {"classpath:config.properties"})
public class CustomConfig {
@Value("${server.host}")
private String host;
@Value("${server.port}")
private int port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
基于注解配置AOP面向切面编程
声明切面类
@Aspect
(切面):通常是⼀个类,⾥⾯可以定义切入点和通知
配置切入点和通知
@Component
//告诉spring,这个一个切面类,里面可以定义切入点和通知
@Aspect
public class LogAdvice {
//切入点表达式
@Pointcut("execution(* net.xdclass.sp.service.VideoServiceImpl.*(..))")
public void aspect(){}
//前置通知
@Before("aspect()")
public void beforeLog(JoinPoint joinPoint){
System.out.println("LogAdvice beforeLog");
}
//后置通知
@After("aspect()")
public void afterLog(JoinPoint joinPoint){
System.out.println("LogAdvice afterLog");
}
}
开启SpringAOP注解配置
@Configuration
@ComponentScan("net.xdclass")
@EnableAspectJAutoProxy //开启了spring对aspect的支持
public class AnnotationAppConfig {
}
效果测试
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAppConfig.class);
VideoService videoService = (VideoService) context.getBean("videoService");
videoService.findById(2);
}
}
环绕通知统计接口耗时
在切面类中配置环绕通知:打印⽅法请求耗时时间
环绕通知获取⽬标方法和参数
//环绕通知
@Around("aspect()")
public void around(JoinPoint joinPoint){
Object target = joinPoint.getTarget().getClass().getName();
System.out.println("调用者="+target);
//目标方法签名
System.out.println("调用方法="+joinPoint.getSignature());
//通过joinPoint获取参数
Object [] args = joinPoint.getArgs();
System.out.println("参数="+args[0]);
long start = System.currentTimeMillis();
System.out.println("环绕通知 环绕前=========");
//执行连接点的方法
try {
((ProceedingJoinPoint)joinPoint).proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("环绕通知 环绕后=========");
System.out.println("调用方法总耗时 time = " + (end - start) +" ms");
}