Spring4 笔记
1. 通过 xml 赋值给 bean
1) 通过set 方法赋值 (必须要有空的构造方法)
<bean id="user" class="com.test.User">
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
<property name="address" value="北京"></property>
</bean>
2) 通过构造方法赋值
<bean id="user2" class="com.test.User">
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
<constructor-arg value="上海"></constructor-arg>
</bean>
3) 装配 list 属性 (实体类中必须先定义好list)
<bean id="user3" class="com.test.User">
<property name="name" value="王五"></property>
<property name="age" value="30"></property>
<property name="address" value="hebei"></property>
<property name="books">
<list>
<ref bean="book"/>
<ref bean="book2"/>
</list>
</property>
</bean>
4) 装配 map 属性 (实体类中必须先定义好 map)
<bean id="user4" class="com.test.User">
<property name="name" value="王五"></property>
<property name="age" value="30"></property>
<property name="address" value="hebei"></property>
<property name="bookMap">
<map>
<entry key="AA" value-ref="book"></entry>
<entry key="BB" value-ref="book2"></entry>
</map>
</property>
</bean>
5) 装配 properties 属性
<bean id="jdbcDatabase" class="com.test.JDBCDatabase">
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">123</prop>
<prop key="jdbcUrl">com.mysql.jdbc.Driver</prop>
<prop key="driverClasss">jdbc:mysql://test</prop>
</props>
</property>
</bean>
6) 声明集合类型的 bean, 也可以是map
<util:list id="books2">
<ref bean="book"/>
<ref bean="book2"/>
</util:list>
7) 简易写法 ref 6) 中的 books2
<bean id="user5" class="com.test.User" p:name="赵六" p:age="50" p:address="shanghai" p:books-ref="books2"></bean>
8) 自动装配 byName 是通过 persion中的set方法来匹配装配项, 如下的: address 和 car (在开发中很少会使用)
<bean id="address" class="com.test2.Address" p:name="北京" p:number="203"></bean>
<bean id="car" class="com.test2.Car" p:name="宝马" p:price="20000000"></bean>
<bean id="persion" class="com.test2.Persion" p:name="张三" autowire="byName"></bean>
byType 是通过类型进行装配(如上的Address类和Car类, 如果有2个同样的类, 就不能装配了)
9) 配置继承 将相同的去掉, 使用 parent="address2" 来实现继承没有的属性
<bean id="address2" class="com.test2.Address" p:name="北京" p:number="203"></bean>
<bean id="address3" p:number="205" parent="address2"></bean>
10) 抽象 bean , 只能用来被继承, 不能被实例化、 如果是非抽象bean , 则必须要有属性值
<bean id="address2" class="com.test2.Address" p:name="北京" p:number="203" abstract="true"></bean>
<bean id="address3" p:number="205" parent="address2"></bean>
11) bean 依赖关系, 如果配置了 depends-on="car" 属性, 则必须要有一个定义了 car 的bean,
12) bean 的作用域 如果配置了 scope="singleton" 属性, 表示在整个bean的生命周期中是 单例的, 只创建这一个bean (默认值为这个)
如果配置了 scope="prototype" 属性, 表示在整个bean的生命周期中是 原型的, 每次会创建一个新的bean
13) 通过bean 链接mysql
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///mysql"></property>
</bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("jdbcBeans.xml");
javax.sql.DataSource dataSource = (javax.sql.DataSource)ctx.getBean("dataSource");
System.out.println(dataSource.getConnection());
14) 通过引用外部文件来获取 链接数据库信息, spring 链接数据库
1> 新建 db.properties 文件, 内容为:
user=root
password=root
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///mysql
2> bean配置文件内容为:
<context:property-placeholder location="classpath:db.properties"/>
3> 配置 bean配置文件内容 类似于 el 表达式的方式来获取
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
</bean>
15) 引用外部函数来动态指定属性值 (SpEl表达式)
<bean id="car" class="com.properties.Car">
<property name="name" value="Aodi"></property>
<property name="price" value="500000"></property>
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI*50}"></property>
</bean>
16) 通过SpEl 表达式来引用其他bean
<property name="car" value="#{car}"></property>
通过SpEl 表达式来引用其他bean中的属性 (动态赋值)
<property name="info" value="#{car.price > 300000 ? '金领' :'白领'}"></property>
17) bean 的生命周期, init2 和 destroy 都是 Car中自定义的方法,在启动这个IOC容器会先调用 init2 方法, 关闭的时候会调用 destroy 方法
执行顺序是: 构造方法----> init ----> main ----> destroy
<bean id="car" class="com.properties.Car" init-method="init2" destroy-method="destroy">
<property name="name" value="Aodi"></property>
</bean>
18) bean 的后置处理器 (检查 bean 的合法性), 这样在这个配置文件下所有的bean都会执行这个后置处理器, 这个配置和在Car类中不需要增加任何东西
1> bean 的配置如下:
<bean class="com.properties.MYBeanPostProcessor"></bean>
2> 后置处理器类的内容如下: 需要实现 BeanPostProcessor 接口
public class MYBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization "+ bean + " "+ beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization "+ bean + " "+ beanName);
return bean;
}
执行流程将会变为: 构造方法 ----> postProcessBeforeInitialization ----> init ----> postProcessAfterInitialization ---- main ----> destroy
19) 静态工厂方法来配置 bean,不需要实例化工厂类, 注意不是配置静态工厂方法实例,而是配置bean实例
1> bean配置内容如下:class指定静态方法工厂类, factory-method指定指定获取指定bean的具体方法,
如果工厂方法需要传入参数, 则使用 constructor-arg 传入参数
<bean id="car1" class="com.staticFactory.StaticFactory" factory-method="getCar">
<constructor-arg value="baoma"></constructor-arg>
</bean>
2> 静态方法类内容如下:
public class StaticFactory {
private static Map<String, Car> cars = new HashMap<String, Car>();
static {
cars.put("aodi", new Car("aodi",300000));
cars.put("baoma", new Car("baoma", 500000));
}
public static Car getCar(String name) {
return cars.get(name);
}
}
20) 实例工厂方法: 需要先实例化工厂, 再实例化 bean
1> bean 代码如下:
<bean id="instenceFactory" class="com.staticFactory.InstenceFactory"></bean>
<bean id="car2" class="com.staticFactory.Car" factory-bean="instenceFactory" factory-method="getCar">
<constructor-arg value="aodi"></constructor-arg>
</bean>
2> 实例工厂代码如下:
public class InstenceFactory {
private Map<String, Car> cars = null;
public InstenceFactory() {
cars = new HashMap<String, Car>();
cars.put("aodi", new Car("aodi", 300000));
cars.put("ford", new Car("ford", 500000));
}
public Car getCar(String name) {
return cars.get(name);
}
}
21) 通过 spring 自带的 FactoryBean 来配置bean
1> bean 配置如下:
<bean id="car3" class="com.staticFactory.CarFactoryBean">
<property name="name" value="BMW"></property>
</bean>
2> 自定义类 CarFactoryBean 代码如下:
public class CarFactoryBean implements FactoryBean<Car>{
private String name;
public void setName(String name) {
this.name = name;
}
public Car getObject() throws Exception {
return new Car(name, 500000);
}
public Class<?> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return true;
}
}
22) 通过注解来配置 bean
1> 扫描annotation包下的所有类和子包下的所有类
<context:component-scan base-package="com.annotation"></context:component-scan>
2> 只扫描 annotation包下的 component包下的所有类
<context:component-scan base-package="com.annotation" resource-pattern="component/*.class"></context:component-scan>
3> 不包含 @Repository 来注解 的类
<context:component-scan base-package="com.annotation" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
4> 只包含 @Repository 来注解 的类 (使用 annotation 来对注解类的过滤)
<context:component-scan base-package="com.annotation" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
5> 不包含具体的类或接口
<context:component-scan base-package="com.annotation">
<context:exclude-filter type="assignable" expression="com.annotation.service.userService.UserService"/>
</context:component-scan>
6> 只包含具体的类或接口 (使用 assignable 来指定对具体类来过滤)
<context:component-scan base-package="com.annotation" use-default-filters="false">
<context:include-filter type="assignable" expression="com.annotation.service.userService.UserService"/>
</context:component-scan>
7> 对 IOC容器中的类里面的属性进行自动装配(也就是说组件之间的相互引用)
例如:@Autowired, 也可以放到 set方法上, @Autowired默认设置的属性都必须在 IOC 容器里管理, 否则会抛异常 找不到 bean
如果容许可以不是 IOC 容器里的bean 可以这样进行设置:@Autowired(required=false)
@Controller
public class UserController {
@Autowired
private UserRespository userRespository;
public void save() {
System.out.println("UserController...");
userRespository.save();
}
}
8> @Autowired 可以用在 数组, 集合, map 上
23) 使用 spring 中的 AOP 来实现 动态代理 前置通知 (顺便看 动态代理实现方式)所需要的包为:
1> 前置通知类 所有通知中可以没有 JoinPoint 参数和其他参数
1.xml 配置文件
<context:component-scan base-package="com.aopImpl"></context:component-scan>
<!-- 使 AspjectJ 注解起作用: 自动为匹配的类生成 代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. 前置通知类: 其中 @Before("execution(public int com.aopImpl.ArithmeticCalculator.*(int, int))")可以是用通配符来匹配
比如 @Before("execution(* com.aopImpl.*.*(int, int))") 这样就表示, 第1* 表示任意返回值,com.aopImpl 第2* 表示包下的所
有类,第3* 表示中的所有方法
@Aspect
@Component
public class loggingAspect {
@Before("execution(public int com.aopImpl.ArithmeticCalculator.*(int, int))") //指定加入的类方法
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("The method "+methodName+" begin with "+args );
}
}
主要有这几种通知
2> 后置通知 (@After)是在方法执行完后或抛出异常时都会执行, 但不能访问方法返回结果, 返回结果需要在返回通知中访问
3> 返回通知 (@AfterReturning) 是在方法正确执行完之后才执行的, 可以访问到返回值
@AfterReturning(value = "execution(* com.aop2.*.*(int, int))", returning="result")
public void afterReturnAop(JoinPoint joinPoint, Object result) {
System.out.println("The afterReturning ..."+joinPoint.getSignature().getName()+" result is "+result);
}
4> 异常通知, 可以指定具体抛出那个异常才去执行: 比如: NullPointerException ex
@AfterThrowing(value = "execution(* com.aop2.*.*(..))", throwing="ex")
public void afterThrowingAop(JoinPoint joinPoint, Exception ex) {
System.out.println("The afterThrowing Exception is : "+ex.getMessage());
}
5> 环绕通知,
/**
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数
* 环绕通知类似于动态代理的全过程, ProceedingJoinPoint 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值, 返回值即为目标方法的返回值
* @param pjd
*/
@Around(value = "execution(* com.aop.*.*(int, int))")
public void aroundMethod(ProceedingJoinPoint pjd) {
String methodName = pjd.getSignature().getName();
try {
//前置通知
System.out.println("The method "+methodName+" 前置通知 with "+ Arrays.asList(pjd.getArgs()) );
//执行目标方法
Object result = pjd.proceed();
//返回通知
System.out.println("The method "+methodName+" 返回通知 with "+ Arrays.asList(pjd.getArgs()) );
} catch (Throwable e) {
//异常通知
System.out.println("The method "+methodName+" 异常通知 with "+ e);
throw new RuntimeException();
}
//后置通知
System.out.println("The method "+methodName+" 后置通知 with "+ Arrays.asList(pjd.getArgs()) );
}
6> 如果有多个切面类,可以使用 @Order(1) 来指定切面优先级, 值越小, 优先级越高, 如:
@Order(1)
@Around(value = "execution(* com.aop.*.*(int, int))")
public void aroundMethod(ProceedingJoinPoint pjd) {
7> 定义切入点表达式, 以便重用 (该方法不需要填入其他代码)
@Pointcut("execution(* com.aop.*.*(int, int))")
public void jointPointExpression() {}
使用如下: <1> 同类中 @Before("jointPointExpression()")
<2> 同包不同类中 @Before("类名.jointPointExpression()") (类名指定义切入点方法的类)
<3> 不同包 @Before("包.类名.jointPointExpression()")
8> 通过xml 来配置通知
Spring4 笔记的更多相关文章
- spring4笔记----报错publicid systemid之间要有空格的解决方法
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www. ...
- spring4笔记----UrlResource访问网络资源读取xml内容
package com.ij34.bean; import java.util.Iterator; import java.util.List; import org.dom4j.Document; ...
- spring4笔记----spring生命周期属性
init-method : 指定bean的初始化方法-spring容器会在bean的依赖关系注入完成后调用该方法 destroy-method :指定bean销毁之前的方法-spring容器将会在销毁 ...
- spring4笔记----“零配置”:spring提供的几个Annotation标注
@Component :标注一个普通的Spring Bean类 @Controller :标注一个控制器组件器 @Service :标注一个业务逻辑组件器 @Repository ...
- spring4笔记----PropertyPlaceholderConfigurer 属性占位符配置器
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/spring username=root password= ...
- spring4笔记----PropertyOverrideConfigureer 重写占位符配置器(图)
- spring4笔记----Spring几种常用的容器后处理器
PropertyPlaceholderConfigurer 属性占位符配置器 PropertyOverrideConfigureer 重写占位符配置器 CustomAutowireConfig ...
- spring4笔记----常见的java的字符类型与xml匹配
private List<String> schools; <property name="schools"> <list> <value ...
- spring4笔记----使用装配注入合作者Bean的三种方式
no :不自动装配 byName :id(name)与setter方法去set前缀,并小写首字母后同名的Bean完成注入,如有多个匹配则抛异常 byType :spring容器找全部bean,如果找到 ...
- spring4笔记----依赖注入的两种形式
设值注入:通过<property.../>元素驱动Spring执行setter的方法 构造注入:通过<constructor-arg.../>元素驱动Spring执行带有参数的 ...
随机推荐
- 无法链接到windows服务
1.先将鼠标移动到桌面右下角的显示桌面按钮处,选择右侧按钮列表中的搜索列表,输入cmd.exe,右击搜索结果,选择以管理员身份运行. 2.然后输入netsh winsock reset catalog ...
- Shiro——认证
引入shiro依赖 <!-- shiro --> <dependency> <!-- shiro-core Required in all environments. - ...
- 7.内网渗透之windows认证机制
文章参考自三好学生域渗透系列文章 看了内网渗透第五篇文章,发现如果想要真正了解PTT,PTH攻击流程,还需要了解windows的认证机制,包括域内的kerberos协议. windows认证机制 在域 ...
- rest 参数和扩展运算符
rest 参数和扩展运算符 rest 参数的形式为 ...变量名:扩展运算符是三个点 .... rest 参数 function add(...values) { console.log(values ...
- jquery.parser.js 的 parseOptions 方法
// target 是DOM元素 // properties 是宿主的属性 $.parser.parseOptions(target,properties); /** * parse options, ...
- 通过vb.net 和NPOI实现对excel的读操作
通过vb.net 和NPOI实现对excel的读操作,很久很久前用过vb,这次朋友的代码是vb.net写的需要一个excel的操作, 就顾着着实现功能了,大家凑合着看吧 Option Explicit ...
- POJ - 2586 Y2K Accounting Bug (找规律)
Accounting for Computer Machinists (ACM) has sufferred from the Y2K bug and lost some vital data for ...
- P1001
原创 问题描述: 当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法. 具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过8位, ...
- Sharepoint2013搜索学习笔记之自定义结果精简分类(八)
搜索结果页左边的结果精简分类是可以根据搜索结果自定义的,在搜索的部门日志结果集页面上我搜索测试关键字,左边分类导航在默认分类的基础上增加了一个日志类型的分类,如下图: 要实现这个效果,导航到之前定义的 ...
- 使用CodeMaid自动程序排版[转]
前言 「使用StyleCop验证命名规则」这篇文章,指引开发人员透过StyleCop这个工具,来自动检验项目中产出的程序代码是否合乎命名规则. [Tool] 使用StyleCop验证命名规则 但是在项 ...