本文接着上次的文章记录我的Spring学习过程:点击打开链接
为一个bean注入值除了可以用property标签,还可以用constructor-arg标签进行配置,要求在相应的类中有相应的构造函数,举id为something的例子。
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <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="app" class="Tools.app"></bean> <bean id="mybean" class="Tools.Mybean" > <property name="name" value="hjy"></property> <property name="age" value="19"></property> <property name="id" value="1008611"></property> <property name="something" ref="something"></property> </bean> <bean id="something" class="Tools.sth"> <constructor-arg name="name" value="xxx"/> <constructor-arg name="type" value="xxx"/> </bean> </beans>sth.java:
package Tools; public class sth { public String name; public String type; sth(String name,String type) { this.name=name; this.type=type; } public void setName(String name) { this.name = name; } public void setType(String type) { this.type = type; } }
bean子标签property标签的属性ref表示引用,ref+bean的id,表示对一个bean的引用,用于一个类的数据中存在另一个类的实例化对象时使用
说一下bean的自动装填,在beans属性中有一个default-autowire,下面是他可以填的值
Bean的自动装配(Autowiring) 1.No:不做任何操作(默认) 2.byname:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配 3.byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生 4.Constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常 Bean的自动装配:在beans标签配置属性 default-autowire="no/byName/byType/constructor" 作用为:省去了在Spring的xml中配置property标签和constructor-arg标签,只需要配置bean标签即可 PS:byName和byType为设值注入,constructor为构造注入; byName要求bean标签的id属性需要和成员变量的名称一致, byType和constructor则跟id无关
No为默认值,不会自动装填,byname属性会遍历该容器所有的bean,按照类中实例的名字来匹配容器中id相同的bean填进去,byType会匹配容器中class和需要实例化的对象的class相同的bean填进去,constructor需要该类有相应的构造函数,这个我一开始没看懂也是实践的出来的
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <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" default-autowire="constructor"> <bean id="app" class="Tools.app"></bean> <bean id="mybean" class="Tools.Mybean" > <property name="name" value="hjy"></property> <property name="age" value="19"></property> <property name="id" value="1008611"></property> </bean> <bean id="something" class="Tools.sth"> <property name="name" value="water"></property> <property name="type" value="liquid"></property> </bean> </beans>Mybean.java:
package Tools; public class Mybean{ private String name; private int age; private int id; private sth something; Mybean(sth something) { this.something=something; } public void setSomething(sth something) { this.something = something; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setId(int id) { this.id = id; } public void Say(String s) { System.out.println(name+","+age+","+id+","+something.name+","+something.type+","+s); } }这样就可以通过构造器来自动找到type相同的bean装填进去
Resources (针对于资源文件的统一接口) A、UrlResource:URL 对应的资源,根据一个 URL 地址即可获取 B、ClassPathResource:获取类路径下的资源 C、FileSystemResource:获取文件系统里面的资源 D、ServletContextResource:ServletContext 封装的资源,用于访问 ServletContext 环境下的资源 E、InputStreamResource:获取输入流封装的资源 F、ByteArrayResource:获取字节数组封装的资源 通过实现 ApplicationContextAware 接口中的方法 setApplicationContext(ApplicationContext applicationContext) Resource resource = applicationContext.getResource("xxx"); classpath:config.txt file:C:\\config.txt ftp:C:\\config.txt http://www.baidu.com/more/
在Spring中可以使用一些注释来代替xml文件中的配置,可以避免xml文件过大,使得代码更简洁,可以省去很多set方法代码
<context:component-scan base-package="包名"/>在xml中beans标签之间加入这个可以自动扫描包下的注释生成bean
Spring中的注释:
可用于生成bean的标签:
@Controller :注解控制器类(控制层 MVC)
@Service :注解服务类(服务层)
@Repository :注解 DAO 类(持久层)
@Component :将普通的 bean 注解到 spring 容器中,相当于配置文件中的<bean id="xxx" class="xxx"/>(不推荐用)
@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Bean:初始化一个bean并注册到springIoc容器加以管理。结合@Configuration(类上)使用,@Bean注解初始化生成的bean,在不指定名称时,是该注解注解的成员方法的名字
eg:
@Bean
public A getA(){return new A();}//该bean在注册到SpringIoc容器里的名称是getA.
指定名称@Bean(name="xx")时,该bean在注册到SpringIoc容器里的名称是xx
@Bean(name="" initMethod="" destroyMethod=""),支持init和destroy,同xxx.xml配置文件效果相同。
几个常用的注释:
@Autowired:用于setter方法 ,成员变量,构造器上,会自动匹配相应的bean注入到成员中
@Required:用于setter方法,参数可以是false,表示不一定要注入值,那么该bean值就为null,一个类只能有一个true方法,为true时表示一定要找到bean并注入值,不常用,可以直接写在Autowired的参数里面
@Qualifier:放在Autowired注释下,加参数表示用特定的bean注入,适用于type一样但是有很多bean的情况
@Resource:和Autowired注释差不多的用法也是查找bean注入值,可以加name=“xxx”的参数相当于Qualifier注释,因为是java ee自带的建议多用这个减少对spring的依赖
@Scope:singleton,prototype表示单例和多例,放在可以生成bean的注释下面使用
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
我写了个简单的小工程测试上面的一些标签:
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="Tools"/> <bean id="testA" class="Tools.mouse"></bean> <bean id="testB" class="Tools.mouse"></bean> </beans>接口类tool.java:
package Tools; public interface tool { public void show(); }
一个类mouse.java:
package Tools; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; public class mouse { public String name; mouse() { name="mouse"; } }
实现类:
computer.java:
package Tools; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service public class computer implements tool { @Autowired @Qualifier("testA") mouse m; public void show() { System.out.println("computer!"+m.name); } }mobile.java:
package Tools; import org.springframework.stereotype.Service; @Service public class mobile implements tool{ public void show() { System.out.println("mobile!"); } }获得context的类:
context.java:
package Tools; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; @Repository public class context { public static ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); }
测试类:
mainTest.java:
package Tools; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; public class mainTest { @Test public void someTest() { ApplicationContext con=context.context; tool thingA= (computer) con.getBean("computer"); thingA.show(); tool thingB=(mobile)con.getBean("mobile"); thingB.show(); } }输出结果:
computer!mouse
mobile!
因为在xml中注册了mouse类的bean有2个,@Autowired下如果不写Qualifier会报错,也可以直接用一个@Resource(name="testA")这种写法代替,用了注释确实是省去了一堆set方法
收藏两篇文章:
https://www.cnblogs.com/xiaoxi/p/5935009.html
https://www.cnblogs.com/xingzc/p/5777814.html
收集慕课网笔记:
Bean 的定义及作用域注解 A、@Controller :注解控制器类(控制层 MVC) B、@Service :注解服务类(服务层) C、@Repository :注解 DAO 类(持久层) D、@Component :将普通的 bean 注解到 spring 容器中,相当于配置文件中的<bean id="xxx" class="xxx"/> 元注解(Meta-annotations) 元注解即是许多 Spring 提供的注解可以作为自己的代码,元注解是一个简单的注解,可以应用到另一个注解 除了 value() 元注解还可以有其他的属性,允许定制 类的自动监测及 Bean 的注册 Spring 可以自动检测类并注册 Bean 到 Applicationcontext 中 <context:annotation-config /> 通过基于 xml 的 Spring 配置 为了能够自动检测到这些类并注册相应的 Bean ,需要 <context:component-scan base-package="xxx" /> <context:component-scan> 包含 <context:annotation-config>,通常使用前者后,就不需要再使用后者 使用过滤器进行自定义扫描 A、默认情况下,类被自动发现并注册 bean 的条件:使用 @Component @Repository @Service @controller 注解或者使用 @Component 的自定义注解 B、可以通过过滤器修改默认注解的行为 C、还可以使用 use-default-filters = "false" 禁用自动发现与注册
@Autowired注解 A、可以通过添加注解给需要该类型的数组的字段或者方法,以提供 ApplicationContext 中的所有特定类型的 Bean B、可以用于装配 key 为 string 的 map C、如果希望数组有序,可以让 Bean 实现 org.springframework.core.Ordered 接口或者使用 @Order 注解 可以使用@Autowaird注解那些众所周知的解析依赖性接口, 比如:BeanFactory,ApplicationContext,Environment,ReaourceLoader,ApplicationEventPublisher,and MessagSource 比如可以声明一个ApplicationContext的一个引用,并使用@Autowaird注解,就可以在当前类中得到IOC的上下文信息,并可以使用上下文信息
按类型自动装配可能有多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围或者指定唯一,也可以用于指定单独的构造器参数或方法参数,也可用于注解集合类型变量; 用法如下: 如果使用bean装配则不需要再Spring XML中配置,直接在bean类中使用 @Qualifier("beanName") 如果需要在Spring XML中配置,则在bean标签下添加<qualifier value="名称"></qualifier>,然后在bean类中使用@Qualifier("名称") 虽然@Resource和@Autowired都可以来完成注入依赖,但它们之间是有区 别的。首先来看一下: a。@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入; b。@Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用; c。@Resource注解是又J2EE提供,而@Autowired是由spring提供,故减少系统对spring的依赖建议使用 @Resource的方式;
property文件是key-value键值对形式的文件, 加载资源文件: <context:property-placeholder location="classpath:/com/acme/jdbc.propertied"/> 加载这个文件后,可以再当前文件中采用${jdbc.url}这种形式来使用配置文件中的内容. 例如: <property name="url" value="${jdbc.url}"/> 如果使用注解则: 在类名前加上: @Configuration @ImportResource("classpath:/com/acme/propertied-config.xml")引入一个资源,对应一个xml文件中包含property_placeholder 在配置文件中使用username的时候需要注意:username输出有时会是登录用户的username,所以一般在配置文件中配置例如jdbc.username的形式以防止混淆.
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct以及@PreDestroy。 @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。 @Resource装配顺序 1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常 2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常 3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常 4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;