一Maven方式创建Spring工程
1.新建项目 选择Maven Project
2.勾选 Create a simple project
3.添加项目信息
- Group id :包名
- Artifact id:标识名
- Name:项目名
4applicationContext.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">
二maven仓库地址
Maven 中央仓库
地址https://mvnrepository.com/">https://mvnrepository.com/
使用国内镜像
创建一个maven的配置文件
参照:
http://maven.apache.org/settings.html">http://maven.apache.org/settings.html
三一些常见配置参数
1depends-on 提前初始化
可以使某个bean在创建前,先创建别的bean
2lazy-init
在容器启动后,bean被使用到的时候才加载。可以使用的lazy-init属性
bean id="person" class="com.msb.Person" lazy-init="false"
3作用域
spring为bean提供了6种作用域,其中4种只有在web-aware的ApplicationContext种才有用。用户也可以创建自定义的作用域。
singleton 、prototype 、websocket、request、session、application
4springmvc项目哪些是单例的???
注意pojo层的实例一定不能是单例的。
4BeanFactory和FactoryBean
BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。
public class Car {
private String brand="abc";
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car>{
public Car getObject() throws Exception {
// TODO Auto-generated method stub
return new Car();
}
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return null;
}
}
applicationContext.xml
<bean id="car" class="CarFactoryBean" ></bean>
测试代码
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
Car c=(Car) ctx.getBean("car");
System.out.println(c.getBrand());
}
}
5循环依赖
当循环依赖的bean都是通过构造器注入依赖的时候,无论这些bean是singleton还是prototype,在获取bean的时候都会失败。
通过属性注入
- 循环依赖的bean都是singleton 成功。单例模式的对象,在spring中直接实例化。
- 循环依赖的bean都是prototype 失败 当Spring容器在创建A时,会发现其引用了B,从而会先去创建B。同样的,创建B时,会先去创建C,而创建C时,又先去创建A。最后A、B、C之间互相等待,谁都没法创建成功
- 同时有singleton和prototype 当先获取的那个bean是singleton时,就会成功,否则失败
四annotation注解注入
使用注解需要导入AOP包
在配置文件中添加Context约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
<!--component-scan可以自动扫描包内容,并注册Bean到Spring容器-->
<context:component-scan base-package="com.msb"></context:component-scan>
1Component注解
在一个类上添加@Component默认会使用首字母小写的类名作为ID注册到Spring容器。
如果需要手动指定Bean Id可以使用@Component("p")
同属@Component的额外三个注解
@Controller @Service @Repository
这三个注意在MVC开发中会经常用到,除了注解名字和Component不一样之外,其余功能都一样。
Spring额外提供这三个注解的目的主要是为了区分MVC中每个类的区别。
2
@Scope
使用注解注册Bean 默认的作用域还是singleton,可以使用@Scope("prototype")改变对象作用域
3给对象注入值
在使用注解给对象注入值的时候,不再需要Get/Set方法
基础类型
使用@Value注解
("小明")
private String name;
对象引用
@Autowired
private Pet MyPet;
使用@Autowired注解
默认是ByType的,如果需要ByName需要配合@Qualifier注解
()
("p2")
private Pet MyPet;
五AOP
1静态代理
使用硬编码的方式增强原有方法
- 优点:可以做到不对目标对象进行修改的前提下,对目标对象进行功能的扩展和拦截。
- 缺点:因为代理对象,需要实现与目标对象一样的接口,会导致代理类十分繁多,不易维护,同时一旦接口增加方法,则目标对象和代理类都需要维护。
package aop;
public interface Human {
public void eat();
}
package aop;
public class Girl implements Human{
public void eat() {
// TODO Auto-generated method stub
System.out.println("Em mmm.. mm..");
}
}
package aop;
public class ProxyGirl implements Human{
private Human human;
public ProxyGirl(){
super();
}
public ProxyGirl(Human human) {
super();
this.human = human;
}
public void eat() {
// TODO Auto-generated method stub
System.out.println("chiqian");
human.eat();
System.out.println("chihou");
}
}
测试类
package aop;
public class Test {
public static void main(String[] args) {
Girl girl = new Girl();
Human proxyGirl = new ProxyGirl(girl);
proxyGirl.eat();
}
}
2动态代理
动态代理是指动态的在内存中构建代理对象(需要我们制定要代理的目标对象实现的接口类型),即利用JDK的API生成指定接口的对象,也称之为JDK代理或者接口代理。
- 目标对象实现了接口 JDK动态代理
package jdkProxy;
public interface HelloService {
public void sayHello(String name);
}
package jdkProxy;
public class HelloServiceImpl implements HelloService {
public void sayHello(String name) {
// TODO Auto-generated method stub
System.out.println("hello"+name);
}
}
package jdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class HelloServiceProxy implements InvocationHandler{
//真实服务对象
private Object target;
/**
* 绑定委托对象并返回一个代理类
*/
public Object bind(Object target){
this.target=target;
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//jdk代理需要提供接口
}
/**
* 通过代理对象调用方法首先进入这个方法
* proxy-代理对象 method-被调用的方法 args-方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("我是动态代理");
Object result=null;
System.out.println("我准备说hello");
result=method.invoke(target, args);
System.out.println("我说过hello了");
return result;
}
}
package jdkProxy;
public class HelloServiceMain {
public static void main(String[] args) {
HelloServiceProxy helloHandler=new HelloServiceProxy();
HelloService proxy=(HelloService) helloHandler.bind(new HelloServiceImpl());
proxy.sayHello("张三");
}
}
2.目标对象没有实现口CGLib
package jdkProxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class HelloServiceCgLib implements MethodInterceptor{
private Object target;
/**
* 创建代理对象
*/
public Object getInstance(Object target){
this.target=target;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.target.getClass());
//回调方法
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// TODO Auto-generated method stub
System.out.println("我是CGLIB动态代理");
System.out.println("我准备说hello");
Object returnObj=proxy.invokeSuper(obj, args);
System.out.println("我说过hello了");
return returnObj;
}
}
package jdkProxy;
public class HelloServiceMain {
public static void main(String[] args) {
HelloServiceCgLib helloCglib=new HelloServiceCgLib();
HelloServiceImpl impl = (HelloServiceImpl) helloCglib.getInstance(new HelloServiceImpl());
impl.sayHello("李四");
}
}