涉及spring的相关概念
1、pojo
2、为了降低java开发的复杂性,spring采用了4中策略
(1)、基于POJO的轻量级和最小侵入性编程
(2)、通过依赖注入和接口编程实现松耦合
(3)、基于切面和惯例进行声明式编程
(4)、通过切面和模板减少样板式代码
3、依赖注入(DI):让相互协作的软件组件保持松耦合
4、面向切面编程(AOP):允许把遍布各处的应用功能分离出来形成可重复的组件。AOP确保POJO保持简单。
5、创建组件之间协作的行为通常称为装配,spring通过应用上下文(application context)装载bean的定义并把它们组装起来
- Spring在配置xml文件的过程中,如果有singleton作用域依赖prototype作用域的bean时,那么singleton作用域的Bean就只有一次的更新机会,它的依赖关系也只是在初始化阶段被设置,导致singleton作用域的Bean的依赖得不到及时更新。
- 解决办法:在bean的文件中配置此<lookup-method/>节点解决
- PropertyPathFactoryBean,
(1)、用来获取目标的属性值,实际上就是目标Bean的getter方法的返回值,获得的值可以 注入给其他的Bean,也可以直接定义为新的bean;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!-- 将指定Bean实例的属性值定义成指定Bean实例 --> <bean id= "son1" class = "org.springframework.beans.factory.config.PropertyPathFactoryBean" > <!-- 确定目标Bean,表明son1 Bean来自哪个Bean的属性 --> <property name= "targetBeanName" value= "person" /> <!-- 确定属性表达式,表明son1 Bean来自目标bean的哪个属性 --> <property name= "propertyPath" value= "son" /> </bean> <!-- 如下定义son2的 Bean,该Bean的age属性不是直接注入 ,而是依赖于其他Bean的属性值 --> <bean id= "son2" class = "org.app.service.Son" > <property name= "age" > <!-- 以下是访问Bean属性的简单方式,这样可以将person Bean的son属性的、 age属性赋值给son2这个bean的age属性--> <bean id= "person.son.age" class = "org.springframework.beans.factory.config.PropertyPathFactoryBean" /> </property> </bean> |
(2)、使用PropertyPathFactoryBean时,
targetBeanName:确定指定目标Bean,确定获取那个Bean的属性值
propertyPath:用于指定属性,确定获取目标Bean的哪个属性值,此处的属性可以直接使用复合属性的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!-- 将基本数据类型的属性值定义成Bean实例 --> <bean id= "theAge2" class = "org.springframework.beans.factory.config.PropertyPathFactoryBean" > <!-- 确定目标Bean,表明theAge2 Bean来自哪个Bean的属性。 此处采用嵌套Bean定义目标Bean --> <property name= "targetObject" > <!-- 目标Bean不是容器中已经存在的Bean, 而是如下的嵌套Bean--> <bean class = "org.crazyit.app.service.Person" > <property name= "age" value= "30" /> </bean> </property> <!-- 确定属性表达式,表明theAge2 Bean来自目标bean的哪个属性 --> <property name= "propertyPath" value= "age" /> </bean> |
- FieldRetrievingFactoryBean类,通过FieldRetrievingFactoryBean获取目标的Field值之后,得到的值可以注入给其他的Bean,也可以直接定义新的Bean
1 2 3 4 5 6 7 8 | <!-- 将java.sql.Connection的TRANSACTION_SERIALIZABLE 的值赋给son的age属性--> <bean id= "son" class = "org.app.service.Son" > <property name= "age" > <bean id= "java.sql.Connection.TRANSACTION_SERIALIZABLE" class = "org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> </property> </bean> |
在使用FieldRetrievingFactoryBean获取field值时,必须指定如下的属性值:
targetClass:所在的目标类或者目标对象,如果需要获得Field是静态字段,则使用targetClass指定目标类。
targetField:用于指定目标Field的Field值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!-- 将Field 值定义成Bean 实例--> <bean id= "theAge1" class = "org.springframework.beans.factory.config.FieldRetrievingFactoryBean" > <!-- targetClass指定Field所在的目标类 --> <property name= "targetClass" value= "java.sql.Connection" /> <!-- targetField指定Field名 --> <property name= "targetField" value= "TRANSACTION_SERIALIZABLE" /> </bean> <!-- 将Field 值定义成Bean实例 --> <bean id= "theAge2" class = "org.springframework.beans.factory.config.FieldRetrievingFactoryBean" > <!-- value指定采用哪个类的哪个静态域值 --> <property name= "staticField" value= "java.sql.Connection.TRANSACTION_SERIALIZABLE" /> </bean> |
- MethodInvokingFactoryBean:通过此工厂,可以讲指定方法的返回值注入到目标的属性值,MethodInvokingFactoryBean用来获取指定方法的返回值;获得的返回值既可以注入到指定的Bean实例的指定属性,也可以直接定义为Bean的实例,代码实例如下:
1 2 3 4 5 6 7 8 9 10 11 12 | <bean id= "son2" class = "org.app.service.Son" > <property name= "age" > <bean class = "org.springframework.beans.factory.config.MethodInvokingFactoryBean" > <!-- targetClass确定目标类,指定调用哪个类 --> <property name= "targetClass" value= "org.app.util.ValueGenerator" /> <!-- targetMethod确定目标方法,指定调用目标 class 的哪个方法。 该方法必须是静态方法--> <property name= "targetMethod" value= "getStaticValue" /> </bean> </property> </bean> |
spring事件有下面两个成员:
1、ApplicationEvent,容器事件,由容器发布
2、ApplicationListener 监听器,可以由容器中的任何监听器Bean担任
(1)先顶一个spring的容器事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package cn.study.basic; import org.springframework.context.ApplicationEvent; public class EmailEvent extends ApplicationEvent { private String address; private String text; public EmailEvent(Object source) { super (source); } public EmailEvent(Object source, String address, String text) { super (source); this .address = address; this .text = text; } public String getAddress() { return address; } public void setAddress(String address) { this .address = address; } public String getText() { return text; } public void setText(String text) { this .text = text; } } |
(2)编写容器监听器代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package cn.study.basic; import org.springframework.context.ApplicationListener; public class EmailListener implements ApplicationListener<EmailEvent> { @Override public void onApplicationEvent(EmailEvent arg0) { System.out.println(arg0 instanceof EmailEvent); if (arg0 instanceof EmailEvent) { EmailEvent ee = (EmailEvent) arg0; System.out.println( "address:" + ee.getAddress()); } else { System.out.println( "container:" + arg0); } } } |
(3)、bean.xml文件中加入如下配置:
1 | <bean class = "cn.study.basic.EmailListener" ></bean> |
(4)、测试方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package cn.study.basic.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.study.basic.EmailEvent; public class TestAMain { @Test public void testApp() throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext( "bean.xml" ); EmailEvent emailEvent = new EmailEvent( "object" , "address" , "test" ); context.publishEvent(emailEvent); } } |
运行代码,执行结果如下所示:
true
address:address
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步