Spring 框架的使用 1


在这里插入图片描述

  Spring 是一个项目管理框架,简化企业级开发,俗称”胶水框架”。

  自定义工厂类做类的实例化。


// mypro.properties
userdao=com.baidu.day.text.dao.impl.UserDaoImpl

// MyUtils.java
public class MyUtils {

    public static Properties properties = null;

    static {
        InputStream resourceAsStream = MyUtils.class.getClassLoader().getResourceAsStream("mypro.properties");
        properties = new Properties();
        try {
            properties.load(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Object getObject(String beanName) {
        String property = properties.getProperty(beanName);
        try {
            Class<?> aClass = Class.forName(property);
            return aClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

// IUserDao.java
public interface IUserDao {
    void show();
}

// UserDaoImpl.java
public class UserDaoImpl implements IUserDao {
    @Override
    public void show() {
        System.out.println("hello spring。");
    }
}

// 测试
IUserDao userDao = (UserDaoImpl)MyUtils.getObject("userdao");
        userDao.show();

  使用 Spring 做类的实例化。
  Spring 工厂特性。饿汉式创建。工厂创建之后,会将 Spring 配置文件中的所有对象都创建完成(饿汉式)。提高程序运行效率。避免多次IO,减少对象创建时间。(概念接近连接池,一次性创建好,使用时直接获取)。


// pom.xml

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.12.RELEASE</version>
    </dependency>
    
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.16</version>
    </dependency>
  </dependencies>

// spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">

    <bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" />

</beans>


// 测试
 ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        IUserDao userDao = (IUserDao) ac.getBean("userDao");
        userDao.show();

  IDEA 添加代码模版。
  Preferences -> Editor -> File And Code Templates。

  单例和多例。

// spring.xml
<!--  scope="prototype" 多例,默认为单例 singleton -->
    <bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" scope="prototype" />


// 测试
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
IUserDao userDao1 = (IUserDao) ac.getBean("userDao");
IUserDao userDao2 = (IUserDao) ac.getBean("userDao");
IUserDao userDao3 = (IUserDao) ac.getBean("userDao");

System.out.println(userDao1);
System.out.println(userDao2);
System.out.println(userDao3);

  控制反转。实际上是类的嵌套实例化。


// IUserService.java

public interface IUserService {
    void show();
}

// UserServiceImpl.java 
// 注意要写set/get
@Data
public class UserServiceImpl implements IUserService {
    private IUserDao userDao;
    @Override
    public void show() {

        userDao.show();
        System.out.println("这是 service");
    }
}

// spring.xml

<bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" scope="prototype" />

// 1
    <bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl" >
<!--      name 对应实例属性名; ref,引用,对应实例的bean id  -->
        <property name="userDao" ref="userdao"></property>
    </bean>

// 2、3
<!--   autowire 自动写入。byName,根据属性名,引入的bean id 和 属性名要一致;byType,根据属性类型 -->
    <bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl" autowire="byName">

    </bean>

// 测试
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        IUserService userService = (IUserService) ac.getBean("userService");
        userService.show();

  依赖注入。实际上就是初始化赋值。


@Data
public class Address {

    private Integer id;
    private String address;

}

// User.java

@Data
public class User {

    private Integer id;
    private String password;
    private String sex;
    private Integer age;

    private Date bornDate;
    private String[] hobbys;
    private Set<String> phones;
    private List<String> names;
    private Map<String,String> countries;
    private Properties files;
    /* 对象s */
    private Address address;

}


// spring.xml 部分代码

<!--  依赖注入   -->
    <bean id="user" class="com.baidu.day.text.entity.User">
<!--    使用set、get方法赋值    -->
        <property name="id" value="1"></property>
        <property name="password" value="123"></property>
        <property name="sex" value="男"></property>
        <property name="age" value="12"></property>

<!--     日期, 固定格式 xxxx/xx/xx -->
        <property name="bornDate" value="2021/1/21"></property>

<!--        数组 -->
        <property name="hobbys">
            <array>
                <value>coding</value>
                <value>read</value>
                <value>write</value>
            </array>
        </property>

<!--        set -->
        <property name="phones">
            <set>
                <value>123</value>
                <value>234</value>
            </set>
        </property>

<!--       list -->
        <property name="names">
            <list>
                <value>admin</value>
                <value>张三</value>
            </list>
        </property>

<!--        map -->
        <property name="countries">
            <map>
                <entry key="cn">
                    <value>china</value>
                </entry>
                <entry key="usa">
                    <value>amarican</value>
                </entry>
            </map>
        </property>

<!--        properties -->
        <property name="files">
            <props>
                <prop key="username">admin</prop>
                <prop key="password">123</prop>
            </props>
        </property>

        <!--    对象 -->
        <property name="address">
            <bean class="com.baidu.day.text.entity.Address">
                <property name="id" value="1"></property>
                <property name="address" value="北京"></property>
            </bean>
        </property>
    </bean>


// 测试
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) ac.getBean("user");
        System.out.println(user);

  构造注入。


// Student.java
public class Student {

    private Integer id;
    private String name;
    private String sex;
    private Integer age;

    public Student(Integer id, String name, String sex, Integer age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
}

// spring.xml
<!--   默认调用无参构造方法,没有会报错 -->
    <bean id="student" class="com.baidu.day.text.entity.Student">

<!--        根据参数名 -->
        <constructor-arg name="id" value="1"></constructor-arg>
        <constructor-arg name="name" value="admin"></constructor-arg>
        <constructor-arg name="sex" value="男"></constructor-arg>
        <constructor-arg name="age" value="12"></constructor-arg>

<!--       根据下标 -->
<!--        <constructor-arg index="0" value="1"></constructor-arg>-->
<!--        <constructor-arg index="1" value="admin"></constructor-arg>-->
<!--        <constructor-arg index="2" value="男"></constructor-arg>-->
<!--        <constructor-arg index="3" value="12"></constructor-arg>-->

<!--       根据参数个数 -->
<!--        <constructor-arg value="1"></constructor-arg>-->
<!--        <constructor-arg value="admin"></constructor-arg>-->
<!--        <constructor-arg value="男"></constructor-arg>-->
<!--        <constructor-arg value="12"></constructor-arg>-->

    </bean>

  对象初始化和销毁。


// Address.java

@Data
public class Address {
    private Integer id;
    private String address;
    
    public void init(){
        System.out.println("初始化了");
    }

    public void destroy(){
        System.out.println("销毁");
    }
}

// spring.xml
	<bean id="address" class="com.baidu.day.text.entity.Address" init-method="init" destroy-method="destroy">
        <property name="id" value="1"></property>
        <property name="address" value="深圳"></property>
    </bean>

  FactoryBean 创建复杂对象。


// MyConnection.java

public class MyConnection implements FactoryBean<Connection> {


    @Override
    public Connection getObject() throws Exception {

        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "admin", "admin");
        return connection;
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }

    // 是否单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}


// spring.xml
<!--  返回的是 getObject 返回的  -->
    <bean id="conn" class="com.baidu.day.text.utils.MyConnection"></bean>

// 测试
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        Connection connection = (Connection) ac.getBean("conn");
        System.out.println(connection);

  代理。就是找个中间人来做事。常用来回调数据。

  静态代理。

// IFangDong.java
public interface IFangDong {
    void zufang();
}

// FangDongImpl.java
public class FangDongImpl implements IFangDong {


    @Override
    public void zufang() {
        System.out.println("租房");
        System.out.println("收钱");
    }
}

// ZuFangProxy.java 
// 代理
@Data
public class ZuFangProxy {

    private IFangDong fangDong = new FangDongImpl();

    public void zufang() {
        System.out.println("发布信息");
        System.out.println("找人看房");

        //
        fangDong.zufang();
    }
}

// 测试
ZuFangProxy z = new ZuFangProxy();
z.zufang();

  动态代理。


// DynamicProxy.java

public class DynamicProxy {

    public static void jdk() {
        // 主要对有实现接口的实现类进行动态代理的生成

        final FangDongImpl fangDong = new FangDongImpl();

        // 设置代理
        InvocationHandler in = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                System.out.println("发布信息");
                System.out.println("找人看房");
                fangDong.zufang();
                return null;
            }
        };

        // 生成代理类
        IFangDong o = (IFangDong) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(), fangDong.getClass().getInterfaces(), in);
        o.zufang();
        System.out.println(o.getClass());
    }

    public static void cglib() {
        // 主要应用于没有实现接口的类,进行动态代理的生成
        final FangDongImpl fangDong = new FangDongImpl();

        Enhancer en = new Enhancer();

        en.setSuperclass(FangDongImpl.class);

        // 设置代理
        en.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("发布信息");
                System.out.println("找人看房");
                fangDong.zufang();
                return null;
            }
        });

        // 生成代理类
        IFangDong o = (IFangDong) en.create();
        o.zufang();
        System.out.println(o.getClass());
    }

    public static void main(String[] args) {
        jdk();

        cglib();
    }

}

  AOP,Aspect Oriented Programming,面向切面编程。


// pom.xml 添加

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.1.16.RELEASE</version>
</dependency>


// MyBefore.java 

public class MyBefore implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("这个是aop前置增强");
        System.out.println("写日志");
    }
}


// spring.xml 部分代码 ,相关的类在上面例子中有
<!-- aop -->
    <bean id="fangdong" class="com.baidu.day.text.proxy.FangDongImpl"></bean>
    <bean id="zufangproxy" class="com.baidu.day.text.proxy.ZuFangProxy">
    <!-- 有属性的引入一定要写 set/get -->
       <property name="fangDong" ref="fangdong"></property>
    </bean>
<!--  声明增强类  -->
    <bean id="mybefore" class="com.baidu.day.text.advice.MyBefore"></bean>

    <aop:config>
    	// 设置切点。zufang 所有同名方法都会走。
        <aop:pointcut id="myPointcut" expression="execution(* zufang(..))"/>
        <aop:advisor advice-ref="mybefore" pointcut-ref="myPointcut"></aop:advisor>
    </aop:config>

</beans>


// 测试
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");

		ZuFangProxy proxy = (ZuFangProxy)ac.getBean("zufangproxy");
		// class com.baidu.day.text.proxy.ZuFangProxy , proxy说明是代理类
        System.out.println(proxy.getClass());
        proxy.zufang();

// 打印,前置打印了两次,是因为zufang 方法名匹配到两次的原因
class com.baidu.day.text.proxy.ZuFangProxy$$EnhancerBySpringCGLIB$$e1f1afde

这个是aop前置增强
写日志
发布信息
找人看房
这个是aop前置增强
写日志
租房
收钱


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值