spring(5)注解
2.ioc
@Configuration://配置,可以使用AnnotationConfigApplicationContext加载
@Import({Student.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//全类名,MyImportSelector需要实现ImportSelector接口,MyImportBeanDefinitionRegistrar需要实现ImportBeanDefinitionRegistrar接口
@Value("李四") //指定值,可以用在set方法,参数,属性上,支持spel表达式
@Bean(value="p1",destroyMethod = "destroy",initMethod = "init")/*注解具有返回值的方法,注入bean容器,destroy在销毁bean之前,init在赋值之前,多实例不会加入bean容器管理,所以不会调用detroy方法*/
@PostConstruct//bean赋值完成之后
@PreDestroy//容器销毁bean之前
@Autowired:自动注入,具有参数require,可以放在参数,方法,属性,构造器上
@Resource与@Autowired用法类似,不支持@Primary的功能
@injection与@Autowired一样,但是少了require属性,需要导入jar
@Primary//默认是自动动装配的首选bean,与@Autowired配合使用
@Scope:singleton为默认值,表示单实例,还有request,session,prototype
@Lookup://在单实例bean依赖多实例bean时使用,一般与@Scope配合使用
@PropertySource({"classpath:"})//导入多个资源文件,保存在环境变量中
@Conditional(WindowCondition.class)//需要实现Condition接口,满足条件的才注册bean,spring底层大量使用该注解,使用在方法上,表示当前方法需要满足条件,注解在类上,表示所有的都需要满足该条件
@Lazy //延迟加载,第一次调用时加载
@Qualifier("p")//指定注入bean的名称
@component,@service,@repository,@controller
@Profile("test")/*默认值defalut,表示被ioc注入,其他值在没有被激活的情况下,不能注入bean,用于数据源的切换等
注入方式:添加运行参数Dspring.profiles.active=test,或者按如下方式激活(按test方式激活)
@org.junit.Test
public void testProfile(){
acac = new AnnotationConfigApplicationContext();
acac.getEnvironment().setActiveProfiles("test");
acac.register(MainConfig.class);
acac.refresh();
String[] names = acac.getBeanDefinitionNames();
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
*/
@ComponentScans(): ComponentScan[] value();
@ComponentScan(value = "cn.springannocation.bean",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Component.class})}, useDefaultFilters = false)
/*属性:useDefaultFilters:在includeFilters是需要使用,因为是默认加载 ; includeFilters/ excludeFilters*/
/*FilterType的枚举值有:ANNOTATION:注解;ASSIGNABLE_TYPE:类型;ASPECTJ:切面表达式(很少用);REGEX:正则;CUSTOM:自定义(需要实现TypeFilter接口)*/
备注:
1)MyImportSelector实现ImportSelector接口,使用@Import({MyImportSelector.class})
public class MyImportSelector implements ImportSelector {
//AnnotationMetadata:当前标注@Import的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String [] strs={"cn.springannocation.bean.Cat"};//全类名的方式
return strs;//不能返回null,否则会出异常,将strs中的内容注入到bean容器
}
}
2)MyImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口,使用@Import({MyImportBeanDefinitionRegistrar.class})
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/*importingClassMetadata:当前标注@Import的所有注解信息
BeanDefinitionRegistry:使用registerBeanDefinition方法手动加载*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//RootBeanDefinition是BeanDefinition子类
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
//Person注册到BeanDefinitionRegistry中,手动注册bean
registry.registerBeanDefinition("name", rootBeanDefinition);
}
}
3)bean工厂
public class MyFactoryBean implements FactoryBean<Cat> {
@Override//获取bean
public Cat getObject() throws Exception {
return new Cat();
}
@Override//获取bean的类型
public Class<?> getObjectType() {
return Cat.class;
}
@Override//是否是单例
public boolean isSingleton() {
return true;
}
}
@Bean("myFactoryBean")
public MyFactoryBean getMyFactoryBean() {
return new MyFactoryBean();
}
@Test
public void testFactoryBean(){
Object bean = acac.getBean("myFactoryBean");
System.out.println(bean.getClass());/输出为class cn.springannocation.bean.Cat,会使用MyFactoryBean中的方法,在id前添加&表示返回的是工厂对象自身,生产对象*/
}
4)InitializingBean与DisposableBean//针对该bean
@Component("mad")
public class MyInitializingBeanAndDisposableBean implements InitializingBean , DisposableBean {
@Value("bb")
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override//赋值完成之后,@PostConstruct类似
public void afterPropertiesSet() throws Exception {
setName("aaa");
System.out.println("afterPropertiesSet...");
}
@Override//容器销毁bean之前,@PreDestroy类似,在多实例中bean容器不会管理,所以不会调用destroy方法
public void destroy() throws Exception {
System.out.println("destroySet...");
}
@Override
public String toString() {
return "MyInitializingBeanAndDisposableBean{" +
"name='" + name + '\'' +
'}';
}
}
6)WindowCondition实现Condition接口
public class WindowCondition implements Condition {
/**
* ConditionContext: 上下文信息
* AnnotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//获取bean工厂
ClassLoader classLoader = context.getClassLoader();//获取类加载器
Environment environment = context.getEnvironment();//获取上下文环境
BeanDefinitionRegistry registry = context.getRegistry();//获取bean的注册信息
registry.containsBeanDefinition("p");//容器中是否含有p
if(environment.getProperty("os.name").contains("Windows")){
System.out.println(environment.getProperty("os.name"));
return true;
}
return false;
}
}
7)FilterType.CUSTOM需要实现TypeFilter接口
/*自定义类型过滤器*/
public class MyTypeFilter implements TypeFilter {
/*是一个一个来扫描添加的
* 返回值为true,那么就会添加到AnnotationConfigApplicationContext容器类
*metadataReader :当前正在扫描的类的信息,包含注解信息,类信息,资源信息等
*MetadataReaderFactory:可以获取其他任何类的信息
* */
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
System.out.println(metadataReader.getAnnotationMetadata());//注解信息
System.out.println(metadataReader.getClassMetadata());//类信息,例如类名含有xxx的加入容器等
System.out.println(metadataReader.getResource());//路径等信息
return false;
}
}
8)xxxaware接口都有相应的xxxawreprocessor接口,每个xxxaware接口都有一个需要实现的方法
BeanClassLoaderAware bean加载器接口
ApplicationContextAware 注入对象
BeanNameAware bean的名称
BeanFactoryAware bean工厂
EmbeddedValueResolverAware 解析spel表达式等
3.aop
@EnableAspectJAutoProxy//开启切面aop
@Enablexxx都是切面的配置
@Aspect//表示当前类为一个切面类,基本都与@Component一起使用
@before,@after,@Pointcut,@Around ,@AfterThrowing, @AfterRunning
execution表达式语法:
execution (“modifiers-pattern ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)throw-pattern”)
说明:execution:匹配执方法的连接点
modifiers-pattern 权限修饰符 支持通配* 可省略
ret-type-pattern 返回值类型 支持通配*
declaring-type-pattern指定方法所属的类 支持通配* 可省略
name-pattern方法名 支持通配
param-pattern ..代表两个任意的参数假如是*则是代表一个任意类型的参数
throw-pattern 声明抛出异常 支持通配 可省略
@Before("execution(* spring2.*.*(int, int))")第一个*表示返回类型 第二个*表示类名 第三个表示方法
备注:
1)AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar //public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)//自定义导入组件
4)事务
@EnableTransactionManagement:开启事务
@Transactional //默认值transactionManager, propagation,isolation,readOnly,rollbackFor,noRollbackFor,timeout(spring中有说明)
4.servlet
1)web每次运行的时候都会扫描meta-inf下的javax.servlet.ServletContainerInitializer文件
实例:如下javax.servlet.ServletContainerInitializer文件
内容cn.springannocation.service.MyServletContainerInitializer
//在servlet8.2.4中看到在在meta-inf建立services下建立一个javax.servlet.ServletContainerInitializer文件,
// 在文件内写全路径,默认servlet运行时会自动加载
//满足@HandlesTypes的类型的子类,实现类的类型(不包含自身),放入Set<Class<?>> c中
@HandlesTypes(value = {})
public class MyServletContainerInitializer implements ServletContainerInitializer {
@Override
//启动是就会运行onStartup方法
//必须在项目启动的时候添加
public void onStartup(Set<Class<?>> c, ServletContext sc) throws ServletException {
FilterRegistration.Dynamic userFilter = sc.addFilter("userFilter", new UserFilter());
userFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),true,"/*");
//可以注册servlet listen filter
}
}
5.springmvc注解
@EnableWebMvc // <mvc:annotation-driven/>,且开启定制功能
WebMvcConfigurer接口的实现类WebMvcConfigurerAdapter
方法
addFormatters 注册类型转换器
addInterceptors 注册拦截器
configureViewResolvers 视图解析器
configureDefaultServletHandling 静态资源的处理等
6.web3.0异步请求处理
在web3.0以前,从require获取线程,到response释放线程是一个线程//可能造成线程线程不能释放导致线程不足。
@WebServlet(value = "async", asyncSupported = true)// asyncSupported = true支持异步
@WebServlet(value = "async",asyncSupported = true)//asyncSupported = true开启异步
public class AsyncServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext startAsync = req.startAsync();
startAsync.start(new Runnable() {
@Override
public void run() {
AsyncContext asyncContext = req.getAsyncContext();
// asyncContext.addListener();添加监听
// asyncContext.setTimeout();连接时间
ServletResponse response = asyncContext.getResponse();
try {
response.getWriter().print("hellowrold");
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
springmvc的异步
@RequestMapping("/async")
//当返回值为Callable的时候springmvc会自动的开启一个异步的处理
//Callable返回的结果,springmvc将再次放入容器,恢复之前的处理,所以会使用两次拦截器
//有主线程池和异步线程池
public Callable<String> async(){
Callable<String> callable = new Callable(){
@Override
public Object call() throws Exception {
return "async";
}
};
return callable;
}
test
@RequestMapping("/deferredResult")
public DeferredResult<String> deferredResult(){
DeferredResult<String> result = new DeferredResult<>((long)2000,"sss");
MyQueue.save(result);
return result;//deferredResult.setResult(oder);触发以后,才能得到真正的返回
}
@RequestMapping("/create")
public String create(){
//UUID是16字节128位长的数字,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符
//为了保证UUID的唯一性,规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、
// 时序等元素,以及从这些元素生成UUID的算法。UUID的复杂特性在保证了其唯一性的同时,意味着只能由计算机生成
String oder= UUID.randomUUID().toString();
DeferredResult deferredResult = MyQueue.poll();
deferredResult.setResult(oder);//这里触发以后, 上述的return result才立即真正的返回;
return "success";
}
public class MyQueue {
private static ConcurrentLinkedQueue<DeferredResult> queue=new
ConcurrentLinkedQueue<>();//基于分片机制管理锁,效率较LinkedQueue高
public static void save (DeferredResult deferredResult){
queue.add(deferredResult);
}
public static DeferredResult poll(){
DeferredResult deferredResult = queue.poll();
return deferredResult;
}
}
备注:其他注解键spring

浙公网安备 33010602011771号