1:给组件中添加组件
1:包扫描+组件标注注解 @Controller @Service @Component @Repository[只能是自己手写的组件],再使用ComponentScan扫描对应的包
2:@Bean[可以导入第三方包里面的组件]
3:@Import[快速给容器导入一个组件]
1.1 包扫描方式
@Service
public class AdminService {}
@ComponentScan({"cn.pertech"}) //springboot下的扫描
public class Application extends SpringBootServletInitializer {}
1.2 @Bean
@Configuration //标记为配置类
public class Config {
@Bean(value = "persion") //向spring mvc注入bean id为persion
@Lazy(value = true) //开启懒加载,当第一次从springioc获取该实例的时候new该对象
@Scope("singleton") //单例模式(默认;当使用prototype多实例模式时,spring只负责创建,不负责销毁)
@Conditional(value=LinuxCondition.class) //条件选择,当环境为linux时,向springioc中注入
public Persion persion() {
return new Persion(18, "里斯");
}
}
//判断系统是否为linux
@Component
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String linux = environment.getProperty("os.name");
//todo 还可以添加其他的条件
if (linux.contains("linux")) return true;
return false;
}
}
1.3@Import
@Import(Red.class) //向spring ioc中注入一个Red的组件
@Configuration
public class Config {}
2:period 生命周期
2.1:singleton 单实例bean在ioc容器创建后就会创建对象,(lazy模式下会延迟加载)
prototype 多实例bean不会被ioc管理,只会帮助创建,不会主动调用销毁,需要开发者手动调用
2.2:初始化与销毁
2.2.1:指定初始化与销毁,使用initMethod
2.2.2:实现接口InitializingBean, DisposableBean
2.2.3:JSR250使用注解 PostConstruct,PreDestroy
2.2.4:BeanPostProcessor:bean的后置处理(不好用)
在bean初始化前后处理一些工作
2.3总结:
1.默认情况下,spring在读取xml文件的时候(读取配置类),就会创建对象。
2.在创建的对象的时候(先调用构造器),会去调用init-method=".."属性值中所指定的方法。
3.对象在被销毁的时候,会调用destroy-method="..."属性值中所指定的方法。(例如调用container.destroy()方法的时候)
4.lazy-init="true",可以让这个对象在第一次被访问的时候创建。
3:assemble 属性赋值
3.1:@Value
3.2:@PropertSource //加载xml配置文件使用此注解
3.3:@Autowired @Qualifier @Resource
Resource 在ioc有两个实现类时,使用name属性获取指定的
Autowired需要借助Qualifier实现
3.4:
备注:配置文件中的值最后都会保存到environment环境变量
4:AOP
面向切面,常用于日志输出
@Aspect //标记为切面
@Component
public class WebLogAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
ThreadLocal<Long> startTime = new ThreadLocal<Long>();
public WebLogAspect() {
this.logger.info("<WebLogAspect> AOP init....");
}
@Pointcut("execution(* cn.pertech.tongmtx.controller..*.*(..))") //切点
public void webLog() {}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
this.logger.info("=======================================<WebLogAspect>=======================================");
this.startTime.set(System.currentTimeMillis());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
this.logger.info("<WebLogAspect> URL : " + request.getRequestURL().toString());
this.logger.info("<WebLogAspect> HTTP_METHOD : " + request.getMethod());
this.logger.info("<WebLogAspect> IP : " + RequestUtils.getRemoteIp(request));
this.logger.info("<WebLogAspect> CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
this.logger.info("<WebLogAspect> ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
this.logger.info("<WebLogAspect> RESPONSE : " + ret);
this.logger.info("<WebLogAspect> SPEND TIME : " + (System.currentTimeMillis() - this.startTime.get()));
long endTime = System.currentTimeMillis();
this.startTime.get();
this.logger.info("<WebLogAspect> 运行时间: " + (endTime - this.startTime.get()) / 1000);
}
5:事务
@Transactional(propagation=Propagation.REQUIRED) //
REQUIRED 两个方法都有事务的时候,第二个方法使用第一个方法的事务
原理:使用的“动态代理”。所以不能使用this调用本类方法,不然事务无效,因为不是被“proxy”调用,没办法加强方法