Spring入门到进阶 - Spring Bean管理 XML方式
2021-05-05 10:27
标签:pass tap toc aop handle 返回 stp spring配置 例子 resources/applicationContext.xml resources/applicationContext.xml 1、采用无参数的构造方法的方式 2、静态工厂实例化方式 3、实例工厂实例化 1、一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称,id属性在IOC容易中必须是唯一的,如果Bean的名称中含有特殊字符,就需要使用name属性 Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此Spring可以在创建和销毁bean的时候调用bean的两个生命周期方法 当bean被载入到容器的时候调用init,当bean从容器中删除的时候调用destory(scope=singleton有效) resources/applicationContext.xml 结果: 对于类成员变量,注入方式有三种 构造函数注入 属性setter方法注入 接口注入(不常用) Spring支持前两种 通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用 使用set方法注入,在Spring配置文件中,通过 第一种,value注入属性为普通类型的,如String,int型 第二种,name为该类中的属性名,ref注入属性为对象的,值为其他bean的id或name 使用p命名空间 为了简化XML文件配置,Spring从2.5开始引入一个新的p名称空间 普通属性:p:属性名="xxx" 引入常量值 属性为其他对象p:属性名-ref="xxx" 引用其它Bean对象 需要在xml配置文件中引入新头部xmlns:p="http://www.springframework.org/shema/p" 实例: (属性注入较为复杂时使用) 可以在#{.}里面调用其它类里面对应的方法 SpEL表达式语言 语法:#{} Spring入门到进阶 - Spring Bean管理 XML方式 标签:pass tap toc aop handle 返回 stp spring配置 例子 原文地址:https://www.cnblogs.com/greycdoer0/p/13192709.html
Spring的工厂类介绍
public class SpringDemo1 {
@Test
/**
* 传统方式开发
*/
public void demo1(){
// UserService userService = new UserServiceImpl();
UserServiceImpl userService = new UserServiceImpl();
// 设置属性:
userService.setName("张三");
userService.sayHello();
}
@Test
/**
* Spring的方式实现
*/
public void demo2(){
// 创建Spring的工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过工厂获得类:
UserService userService = (UserService) applicationContext.getBean("userService");
userService.sayHello();
}
@Test
/**
* 读取磁盘系统中的配置文件
*/
public void demo3(){
// 创建Spring的工厂类:
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("c:\\applicationContext.xml");
// 通过工厂获得类:
UserService userService = (UserService) applicationContext.getBean("userService");
userService.sayHello();
}
@Test
/**
* 传统方式的工厂类:BeanFactory
*/
public void demo4(){
// 创建工厂类:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 通过工厂获得类:
UserService userService = (UserService) beanFactory.getBean("userService");
userService.sayHello();
}
/**
* 传统方式的工厂类:BeanFactory
*/
@Test
public void demo5(){
// 创建工厂类:
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("c:\\applicationContext.xml"));
// 通过工厂获得类:
UserService userService = (UserService) beanFactory.getBean("userService");
userService.sayHello();
}
}
Bean的实例化三种方式
public class Bean1 {
public Bean1(){
System.out.println("Bean1被实例化了...");
}
}
@Test
public void demo1(){
// 创建工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过工厂获得类的实例:
Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
}
public class Bean2 {
}
// Bean2的静态工厂
public class Bean2Factory {
public static Bean2 createBean2(){
System.out.println("Bean2Factory的方法已经执行了...");
return new Bean2();
}
}
@Test
public void demo2(){
// 创建工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过工厂获得类的实例:
Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");
}
public class Bean3 {
}
// Bean3的实例工厂
public class Bean3Factory {
public Bean3 createBean3(){
System.out.println("Bean3Factory执行了...");
return new Bean3();
}
}
@Test
public void demo3(){
// 创建工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过工厂获得类的实例:
Bean3 bean3 = (Bean3)applicationContext.getBean("bean3");
}
Bean的常用配置
2、class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例
Bean的作用域(scope属性):
1、singleton(默认值)在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在;
2、prototype:每次调用getBean()时都会返回一个新的实例;
3、request:每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境;
4、session:同一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean。该作用域仅适用于WebApplicationContext环境Spring容器中Bean的生命周期
Bean的生命周期的完整过程
setBeanFactory或者上下文对象setApplicationContext
postProcessAfterInitialization
customerDestroyBeanPostProcessor的作用
public class UserDaoImpl implements UserDao {
@Override
public void findAll() {
System.out.println("查询用户。。。");
}
@Override
public void save() {
System.out.println("保存用户。。。");
}
@Override
public void update() {
System.out.println("修改用户。。。");
}
@Override
public void delete() {
System.out.println("删除用户。。。");
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//System.out.println("第五步:初始化前方法...");
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
//System.out.println("第八步:初始化后方法...");
if ("userDao".equals(beanName)) {
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("权限校验===================");
return method.invoke(bean, args);
}
return method.invoke(bean, args);
}
});
return proxy;
} else {
return bean;
}
}
}
@Test
public void demo2(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Man man = (Man)applicationContext.getBean("man");
man.run();
applicationContext.close();
}
1、第一个proxy是Proxy.newProxyInstance得到的实例。而第二个proxy是InvocationHandler中的invoke方法的参数名。
2、这里的method属性传入的是Method类的对象,并不是一个名字。这个method对象是用真正的方法名,由方法名和形参抽象出Method对象。
3、args[]中传入的是原方法执行所需要的参数,由于参数可能有多个,所以使用数组。
4、这里不能返回this,invoke方法的返回值是代理类实例。this是当前对象的实例也就是InvocationHandler的实例。
5、method.invoke(o, args)方法,用来执行对象o的目标方法。在课程中的例子实际上就是那个UserDaoImpl对象的save方法。method.invoke方法的返回值是原方法的返回值。method.invoke方法的作用实际和直接“对象.方法名”调用作用是相同的
6、不能直接返回proxy对象。传入的参数proxy在我们重写的逻辑中没有直接用到,这只是父类中规定好的参数,我们重写时需要遵循。如果不return method.invoke就不会调用到想要调用的方法了。
因为我们增强时返回的是Proxy.newProxyInstance的实例,即外面的proxy代理对象。将来我们要使用它来进行调用,代理在调用的时候会自动调用invoke从而达到增强效果。如果不使用method.invoke就不会调用到真正的类的方法了。
如果同学还是不太理解,建议同学配合看一下后面的SpringAOP的 2-1 节JDK的动态代理课程
Spring的属性注入
构造方法注入
构造器中注入在set方法的属性注入
p名称空间的属性注入
Spring的属性注入-SqEL注入
#{‘hello‘} : 使用字符串
#{beanId} : 使用另一个bean
#{beanId.content.toUpperCase()} : 使用指定名属性,并使用方法
#{T(java.lang.Math).PI} : 使用静态字段或方法
复杂类型的属性注入
文章标题:Spring入门到进阶 - Spring Bean管理 XML方式
文章链接:http://soscw.com/index.php/essay/82689.html