Spring再次学习(1)
程序员文章站
2023-08-29 18:03:57
时隔一年多,在掌握了Spring、SpringBoot、SpringCloud之后 我再次回头,重新学习Spring框架 回顾以前的内容: 组件注册: 最早使用,是XML的方式: 导入依赖: 一个实体类: package org.dreamtech.bean; public class Person ......
时隔一年多,在掌握了spring、springboot、springcloud之后
我再次回头,重新学习spring框架
回顾以前的内容:
组件注册:
最早使用,是xml的方式:
导入依赖:
<dependency> <groupid>org.springframework</groupid> <artifactid>spring-context</artifactid> <version>4.3.12.release</version> </dependency>
一个实体类:
package org.dreamtech.bean; public class person { private string name; private integer age; @override public string tostring() { return "person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public person() { } public person(string name, integer age) { this.name = name; this.age = age; } public string getname() { return name; } public void setname(string name) { this.name = name; } public integer getage() { return age; } public void setage(integer age) { this.age = age; } }
xml:
<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"> <bean id="person" class="org.dreamtech.bean.person"> <property name="name" value="张三"/> <property name="age" value="18"/> </bean> </beans>
测试类:
package org.dreamtech; import org.dreamtech.bean.person; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class maintest { public static void main(string[] args) { applicationcontext applicationcontext = new classpathxmlapplicationcontext("beans.xml"); person bean = (person) applicationcontext.getbean("person"); system.out.println(bean); } }
打印:
person{name='张三', age=18}
完成
后来,开始使用注解方式,不需要xml配置
写一个配置类:
package org.dreamtech.config; import org.dreamtech.bean.person; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; /** * 配置类 */ @configuration public class mainconfig { @bean public person person(){ return new person("李四",20); } }
测试类:
package org.dreamtech; import org.dreamtech.bean.person; import org.dreamtech.config.mainconfig; import org.springframework.context.applicationcontext; import org.springframework.context.annotation.annotationconfigapplicationcontext; public class maintest { public static void main(string[] args) { applicationcontext applicationcontext = new annotationconfigapplicationcontext(mainconfig.class); person bean = applicationcontext.getbean(person.class); system.out.println(bean); } }
打印:
person{name='李四', age=20}
扫描bean:扫描@controller@service等
在xml中的方式是:
<context:component-scan base-package="org.dreamtech.bean"/>
注解方式是:
@componentscan(value = "org.dreamtech")
根据我们开发常用的架构,新建类:
package org.dreamtech.controller; import org.springframework.stereotype.controller; @controller public class bookcontroller { }
package org.dreamtech.service; import org.springframework.stereotype.service; @service public class bookservice { }
package org.dreamtech.dao; import org.springframework.stereotype.repository; @repository public class bookdao { }
然后查看spring容器中所有的bean:
package org.dreamtech.test; import org.dreamtech.config.mainconfig; import org.junit.test; import org.springframework.context.annotation.annotationconfigapplicationcontext; public class ioctest { @test public void test() { annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(mainconfig.class); string[] definitionnames = applicationcontext.getbeandefinitionnames(); for (string name : definitionnames) { system.out.println(name); } } }
打印如下:
org.springframework.context.annotation.internalconfigurationannotationprocessor org.springframework.context.annotation.internalautowiredannotationprocessor org.springframework.context.annotation.internalrequiredannotationprocessor org.springframework.context.annotation.internalcommonannotationprocessor org.springframework.context.event.internaleventlistenerprocessor org.springframework.context.event.internaleventlistenerfactory mainconfig bookcontroller bookdao bookservice person
在扫描的时候,可以进行过滤,指定哪些需要扫描,哪些不需要:
比如我想排除controller注解类的扫描:
@componentscan(value = "org.dreamtech", excludefilters = { @componentscan.filter(type = filtertype.annotation, classes = {controller.class}) })
测试成功
比如我只想扫描controller注解类:
@componentscan(value = "org.dreamtech", includefilters = { @componentscan.filter(type = filtertype.annotation, classes = {controller.class}) })
测试失败
原因:需要禁用掉默认扫描规则
@componentscan(value = "org.dreamtech", includefilters = { @componentscan.filter(type = filtertype.annotation, classes = {controller.class})}, usedefaultfilters = false)
以上是按照注解进行过滤的,实际上还有很多其他的方式,但是不经常使用
比如:指定类、aspectj表达式、正则表达式、自定义
排除指定类(包括子类等)
@componentscan(value = "org.dreamtech", excludefilters = { @componentscan.filter(type = filtertype.annotation, classes = {controller.class}), @componentscan.filter(type = filtertype.assignable_type, classes = {bookservice.class})} )
值得关注的是自定义规则:需要实现一个typefilter接口
我自定义只能扫描到包含字符串"er"的类
package org.dreamtech.config; import org.dreamtech.bean.person; import org.dreamtech.service.bookservice; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.componentscan; import org.springframework.context.annotation.configuration; import org.springframework.context.annotation.filtertype; import org.springframework.core.type.filter.typefilter; import org.springframework.stereotype.controller; /** * 配置类 */ @configuration @componentscan(value = "org.dreamtech", includefilters = { @componentscan.filter(type = filtertype.custom, classes = {mytypefilter.class})}, usedefaultfilters = false ) public class mainconfig { @bean public person person() { return new person("李四", 20); } }
package org.dreamtech.config; import org.springframework.core.io.resource; import org.springframework.core.type.annotationmetadata; import org.springframework.core.type.classmetadata; import org.springframework.core.type.classreading.metadatareader; import org.springframework.core.type.classreading.metadatareaderfactory; import org.springframework.core.type.filter.typefilter; import java.io.ioexception; public class mytypefilter implements typefilter { /** * 实现 * * @param metadatareader 当前正在扫描的类 * @param metadatareaderfactory 可以获取到其他任何类的信息 * @return 是否匹配 * @throws ioexception 异常 */ public boolean match(metadatareader metadatareader, metadatareaderfactory metadatareaderfactory) throws ioexception { //获取当前扫描类注解信息 annotationmetadata annotationmetadata = metadatareader.getannotationmetadata(); //获取当前扫描类的类信息 classmetadata classmetadata = metadatareader.getclassmetadata(); //获取当前扫描类的路径 resource resource = metadatareader.getresource(); string classname = classmetadata.getclassname(); system.out.println("[-------------" + classname + "-------------]"); if (classname.contains("er")) { return true; } return false; } }
测试后打印:
[-------------org.dreamtech.bean.person-------------] [-------------org.dreamtech.config.mytypefilter-------------] [-------------org.dreamtech.controller.bookcontroller-------------] [-------------org.dreamtech.dao.bookdao-------------] [-------------org.dreamtech.maintest-------------] [-------------org.dreamtech.service.bookservice-------------] [-------------org.dreamtech.test.ioctest-------------] org.springframework.context.annotation.internalconfigurationannotationprocessor org.springframework.context.annotation.internalautowiredannotationprocessor org.springframework.context.annotation.internalrequiredannotationprocessor org.springframework.context.annotation.internalcommonannotationprocessor org.springframework.context.event.internaleventlistenerprocessor org.springframework.context.event.internaleventlistenerfactory mainconfig person mytypefilter bookcontroller bookservice
下一篇: 爸爸是前车之鉴